单链表各种操作的C语言实现.docx

上传人:b****5 文档编号:3306917 上传时间:2022-11-21 格式:DOCX 页数:16 大小:20.76KB
下载 相关 举报
单链表各种操作的C语言实现.docx_第1页
第1页 / 共16页
单链表各种操作的C语言实现.docx_第2页
第2页 / 共16页
单链表各种操作的C语言实现.docx_第3页
第3页 / 共16页
单链表各种操作的C语言实现.docx_第4页
第4页 / 共16页
单链表各种操作的C语言实现.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

单链表各种操作的C语言实现.docx

《单链表各种操作的C语言实现.docx》由会员分享,可在线阅读,更多相关《单链表各种操作的C语言实现.docx(16页珍藏版)》请在冰豆网上搜索。

单链表各种操作的C语言实现.docx

单链表各种操作的C语言实现

单链表各种操作的C语言实现

(一)2010-07-3113:

41:

43

分类:

C/C++

    最近,从新复习了一下数据结构中比较重要的几个部分,现在把自己的成果记录下来,主要就是仿照严蔚敏的《数据结构》(C语言版),中的例子和后面的习题进行改编的。

首先,是单链表的各种实现,其中,包含了一些常考的知识点。

例如,单链表的逆置,单链表的合并,找到单链表的中间节点等的算法实现。

  下面这个是单链表的结构体的定义:

typedefstructLNode

{

 ElemTypedata;

 structLNode*next;

}LinkList;

 下面的基本的单链表的操作:

其中,有一些宏,没有给出他们的一些定义,者可以通过,严蔚敏的《数据结构》(C语言版),查看得到。

/*功能:

构建一个空的带头节点的单链表*/

StatusInitList(structLNode**L)

{

  (*L)=(structLNode*)malloc(sizeof(structLNode));//产生头节点

  if(!

*L)

   exit(OVERFLOW);

  (*L)->next=NULL;

  returnOK;

}

/*销毁线性表*/

StatusDestroyList(structLNode*L)

{

  structLNode*q;

  while(L)

  {

    q=L->next;

    free(L);

    L=q;

  }

  returnOK;

}

/*将L重置为空表*/

StatusClearList(structLNode*L)

{

  LinkList*p,*q;

  p=L->next;

  while(p)

  {

    q=p->next;

    free(p);

    p=q;

  }

  L->next=NULL;

  returnOK;

}

/*判断链表是否为空表*/

StatusListEmpty(LinkList*L)

{

  if(L->next)

  {

    returnFALSE;

  }

  else

  {

    returnTRUE;

    

  }

}

/*返回单链表中元素的个数*/

intListLength(structLNode*L)

{

  inti=0;

  LinkList*p=L->next;

  while(p)

  {

    i++;

    p=p->next;

  }

  returni;

}

/*L为带头节点的单链表的头指针,当第i个元素存在时,其值赋给e,并返回OK*/

StatusGetElem(structLNode*L,inti,ElemType*e)

{

  intj=1;

  LinkList*p=L->next;

  while(p&&j

  {

    p=p->next;

    j++;

  }

  if(!

p||j>i)

    returnERROR;

  *e=p->data;

  returnOK;

}

/*返回L中第一个与e满足关系compare()的数据元素的位序,

 若给存在返回值为0,compare()是数据元素的判定函数*/

intLocateElem(structLNode*L,ElemTypee,Status(*compare)(ElemType,ElemType))

{

  inti=0;

  LinkList*p=L->next;

  while(p)

  {

    i++;

    if(compare(p->data,e))

      returni;

    p=p->next;

  }

  return0;

}

/*所cur_e是L中的数据元素,且给就第一个,则用pre_e返回它的前驱*/

StatusPriorElem(structLNode*L,ElemTypecur_e,ElemType*pre_e)

{

  LinkList*q,*p=L->next;

  while(p->next)

  {

    q=p->next;//q指向p的后继

    if(q->data==cur_e)

    {

      *pre_e=p->data;

      returnOK;

    }

    p=q;

  }

  returnINFEASIBLE;

  

}

/*若cur_e是L中的数据元素,且不是最后一个,则用next_e返回它的后继*/

StatusNextElem(structLNode*L,ElemTypecur_e,ElemType*next_e)

{

  LinkList*p;

  p=L->next;

  while(p->next)

  {

    if(p->data==cur_e)

    {

     *next_e=p->next->data;

      returnOK;

    }

    p=p->next;

  }

  returnINFEASIBLE;

}

/*在带头节点的单链表L中的第i个位置之前插入元素e*/

StatusListInsert(structLNode*L,inti,ElemTypee)

{

  intj=0;

  structLNode*p=L,*s=NULL;

  while(p&&j

  {

    p=p->next;

    j++;

  }

  if(!

p||j>i-1)

    returnERROR;

  s=(structLNode*)malloc(sizeof(structLNode));

  if(!

s)

    printf("mallocerror~\n");

  //p->next=s;

  s->data=e;

  //p->next=s;

   s->next=p->next;

   p->next=s;

   //s->next=NULL;

  //p=s;

  returnOK;

}

/*在带头节点的单链表中删除第i个元素,并有e返回其值*/

StatusListDelete(LinkList*L,inti,ElemType*e)

{

 

  LinkList*p=L,*q;

  

   intj=0;

  while(p->next&&j

  {

    p=p->next;

    j++;

  }

  if(!

p->next||j>i-1)

    returnERROR;

  q=p->next;

  p->next=q->next;

  *e=q->data;

  free(q);

  returnOK;

  }

/*依次对L的每个元素调用vi(),打印输出语句*/

StatusListTraverse(structLNode*L,void(*vi)(ElemType))

{

  LinkList*p=L->next;

  while(p)

  {

    vi(p->data);

    p=p->next;

  }

  printf("\n");

  returnOK;

}

/*对单链表进行排序处理*/

structLNode*sort(structLNode*head)

{

  LinkList*p;

  intn,i,j;

  inttemp;

  n=ListLength(head);

  if(head==NULL||head->next==NULL)

    returnhead;

  p=head->next;

  for(j=1;j

  {

    p=head->next;

    for(i=0;i

    {

      if(p->data>p->next->data)

      {

        temp=p->data;

        p->data=p->next->data;

        p->next->data=temp;

      }

      p=p->next;

    }

  }

  returnhead;

}

/*对单链表进行逆置*/

LinkList*reverse(LinkList*head)

{

  LinkList*p1,*p2=NULL,*p3=NULL;

  if(head==NULL||head->next==NULL)

    returnhead;

  p1=head->next;

  while(p1!

=NULL)

  {

    p3=p1->next;

    p1->next=p2;

    p2=p1;

    p1=p3;

 }

 head->next=p2;

  //head=p2;

  returnhead;

}

Statusequal(ElemTypec1,ElemTypec2)

{

  if(c1==c2)

    returnTRUE;

  else

    returnFALSE;

}

/*将所有在线性表Lb中但不在La中的数据元素插入到La中*/

voidUnion(LinkList*La,LinkList*Lb)

{

  ElemType*e;

  intLa_len,Lb_len;

  inti;

  La_len=ListLength(La);

  Lb_len=ListLength(Lb);

  for(i=1;i<=Lb_len;i++)

  {

    GetElem(Lb,i,e);//取Lb中第i个元素赋给e

    if(!

LocateElem(La,*e,equal))//La中不存在和e相同的元素,则插入

      ListInsert(La,++La_len,*e);

  }

}

voidprint(ElemTypec)

{

  printf("%4d",c);

}

/*合并两个单链表,La和Lb中的数据是按非递减排列,归并后的Lc还是安非递减排列*/

voidMergeList(LinkList*La,LinkList*Lb,LinkList**Lc)

{

  inti=1,j=1,k=0;

  intLa_len,Lb_len;

  ElemType*ai,*bj;

  ai=(ElemType*)malloc(sizeof(ElemType));

  bj=(ElemType*)malloc(sizeof(ElemType));

  

  InitList(Lc);

  La_len=ListLength(La);

  Lb_len=ListLength(Lb);

  while(i<=La_len&&j<=Lb_len)

  {

    GetElem(La,i,ai);

    GetElem(Lb,j,bj);

    if(*ai<*bj)

    {

      ListInsert(*Lc,++k,*ai);

      ++i;

    }

    else

    {

      ListInsert(*Lc,++k,*bj);

      ++j;

    }

  }

  while(i<=La_len)

  {

    GetElem(La,i++,ai);

    ListInsert(*Lc,++k,*ai);

  }

  while(j<=Lb_len)

  {

    GetElem(Lb,j++,bj);

    ListInsert(*Lc,++k,*bj);

  }

}

/*只遍历一次,找到单链表中的中间节点

 1定义两个指针,一个指针每次移动两个步长(快指针),另一个指针每次移动一个数据(慢指针)

 2.当快指针到达链表尾部的时候,慢指针就到了链表的中间节点

在程序中也可以判断一个单链表是否有环,如果快指针一定能够追赶上慢指针,否则就会以NULL结束*/

LinkList*Searchmid(LinkList*head)

{

  if(NULL==head)

    returnNULL;

  if(head->next==NULL)

    returnhead;

  if(head->next->next==NULL)

    returnhead;

  

  LinkList*mid=head;

  LinkList*p=mid->next;

  

  while((p!

=NULL)&&(NULL!

=p->next))

  {

    mid=mid->next;

    p=p->next->next;

  }

  returnmid;

}

下面主要是单链表的一个测试的程序。

Statuscomp(ElemTypec1,ElemTypec2)

{

  if(c1==c2)

    returnTRUE;

  else

    returnFALSE;

}

voidvisit(ElemTypec)

{

  printf("%4d",c);

}

voidmain()

{

  LinkList*L;

  LinkList*mid;

  mid=(structLNode*)malloc(sizeof(structLNode));

  

  ElemType*e,e0,*e1;

  Statusi;

  intj,k;

  e=(ElemType*)malloc(sizeof(ElemType));

  e1=(ElemType*)malloc(sizeof(ElemType));

  

  i=InitList(&L);

  for(j=1;j<=6;j++)

  {

    i=ListInsert(L,1,j);

  }

  printf("在L的表头依次插入1~6后:

L=");

    ListTraverse(L,visit);

    printf("L中间节点的值为mid=:

");

    mid=Searchmid(L);

     printf("%d\n",mid->data);

    

      printf("L逆置后的输出:

L=");

      ListTraverse(reverse(L),visit);

    printf("L排序后依次为:

L=");

    ListTraverse(sort(L),visit);

  

    

  i=ListEmpty(L);

  printf("L是否为空:

i=%d(1:

是,0:

否)\n",i);

  i=ClearList(L);

  printf("清空L后:

L=");

  ListTraverse(L,visit);

  i=ListEmpty(L);

  printf("L是否为空:

i=%d\n",i);

  for(j=1;j<=10;j++)

  {

    ListInsert(L,j,j);

  }

  printf("在L的表尾依次插入1~10后:

L=");

  ListTraverse(L,visit);

  GetElem(L,5,e);

  printf("第5个元素的值为:

%d\n",*e);

  for(j=0;j<=1;j++)

  {

    k=LocateElem(L,j,comp);

    if(k)

      printf("第%d个元素的值为%d\n",k,j);

    else

      printf("没有值为%d的元素\n",j);

  }

  for(j=1;j<=2;j++)

  {

    GetElem(L,j,e1);

    i=PriorElem(L,*e1,e);

    if(i==INFEASIBLE)

      printf("元素%d无前驱\n",*e1);

    else

      printf("元素%d的前驱为:

%d\n",*e1,*e);

  }

  for(j=ListLength(L)-1;j<=ListLength(L);j++)

  {

    GetElem(L,j,e1);

    i=NextElem(L,*e1,e);

    if(i==INFEASIBLE)

      printf("元素%d无后继\n",*e1);

    else

      printf("元素%d的后继为:

%d\n",*e1,*e);

  }

   k=ListLength(L);

  for(j=k+1;j>=k;j--)

  {

    i=ListDelete(L,j,e);

    if(i==ERROR)

      printf("删除第%d个数据失败\n",j);

    else

      printf("删除的元素为:

%d\n",*e);

  }

  printf("依次输出L的元素:

");

    ListTraverse(L,visit);

  DestroyList(L);

  printf("销毁L后:

L=%u\n",L);

  printf("*************************************************\n");

  LinkList*La,*Lb;

  i=InitList(&La);

  if(i==1)

    for(j=1;j<=5;j++)

      i=ListInsert(La,j,j);

  printf("La=");

  ListTraverse(La,print);

  InitList(&Lb);

  for(j=1;j<=5;j++)

    i=ListInsert(Lb,j,2*j);

  printf("Lb=");

  ListTraverse(Lb,print);

  Union(La,Lb);

  printf("newLa=");

  ListTraverse(La,print);

  printf("*************************************************\n");

  LinkList*La_1,*Lb_1,*Lc_1;

  inta[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20};

  InitList(&La_1);

  for(j=1;j<=4;j++)

    ListInsert(La_1,j,a[j-1]);

  printf("La_1=");

  ListTraverse(La_1,print);

  InitList(&Lb_1);

  for(j=1;j<=7;j++)

    ListInsert(Lb_1,j,b[j-1]);

  printf("Lb_1=");

  ListTraverse(Lb_1,print);

  MergeList(La_1,Lb_1,&Lc_1);

  printf("Lc_1=");

  ListTraverse(Lc_1,print);

}

下面是在Linux下的部分运行结果:

在L的表头依次插入1~6后:

L=654321

L中间节点的值为mid=:

4

L逆置后的输出:

L=123456

L排序后依次为:

L=123456

L是否为空:

i=0(1:

是,0:

否)

清空L后:

L=

L是否为空:

i=1

在L的表尾依次插入1~10后:

L=12345678910

第5个元素的值为:

5

没有值为0的元素

第1个元素的值为1

元素1无前驱

元素2的前驱为:

1

元素9的后继为:

10

元素10无后继

删除第11个数据失败

删除的元素为:

10

依次输出L的元素:

123456789

销毁L后:

L=7954544

*************************************************

La=12345

Lb=246810

newLa=123456810

*************************************************

La_1=35811

Lb_1=2689111520

Lc_1=235688911111520

/*功能:

构建一个空的带头节点的单链表*/

StatusInitList_CL(structLNode**L)

{

  (*L)=(structLNode*)malloc(sizeof(structLNode));//产生头节点

  if(!

*L)

   exit(OVERFLOW);

  (*L)->next=*L;

  returnOK;

}

/*销毁线性表*/

StatusDestroyList_CL(structLNode*L)

{

  structLNode*q=L->next,*p=(L)->next;

  while(q!

=(L))

  {

    q=L->next;

     free(L);

    L=q;

  }

  free(L);

  L=NULL;

  returnOK;

}

/*将L重置为空表*/

StatusClearList_CL(structLNode*L)

{

  LinkList*p,*q;

   L=L->next;

  p=L->next;

  while(p!

=L)

  {

    q=p->next;

    free(p);

    p=q;

  }

  L->next=L;

  returnOK;

}

/*判断链表是否为空表*/

StatusListEmpty_CL(LinkList*L)

{

  if(L->next==L)

  {

    returnTRUE;

  }

  else

  {

    re

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1