c语言链表.doc

上传人:b****1 文档编号:223221 上传时间:2022-10-06 格式:DOC 页数:12 大小:32KB
下载 相关 举报
c语言链表.doc_第1页
第1页 / 共12页
c语言链表.doc_第2页
第2页 / 共12页
c语言链表.doc_第3页
第3页 / 共12页
c语言链表.doc_第4页
第4页 / 共12页
c语言链表.doc_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

c语言链表.doc

《c语言链表.doc》由会员分享,可在线阅读,更多相关《c语言链表.doc(12页珍藏版)》请在冰豆网上搜索。

c语言链表.doc

---------

一、单链表的建立

  有了动态内存分配的基础,要实现链表就不难了。

  所谓链表,就是用一组任意的存储单元存储线性表元素的一种数据结构。

  链表又分为单链表、双向链表和循环链表等。

我们先讲讲单链表。

  所谓单链表,是指数据接点是单向排列的。

一个单链表结点,其结构类型分为两部分:

  1、数据域:

用来存储本身数据

  2、链域或称为指针域:

用来存储下一个结点地址或者说指向其直接后继的指针。

  例:

  typedefstructnode

  {

  charname[20];

  structnode*link;

  }stud;

  这样就定义了一个单链表的结构,其中charname[20]是一个用来存储姓名的字符型数组,指针*link是一个用来存储其直接后继的指针。

  定义好了链表的结构之后,只要在程序运行的时候爱数据域中存储适当的数据,如有后继结点,则把链域指向其直接后继,若没有,则置为NULL。

  下面就来看一个建立带表头(若未说明,以下所指链表均带表头)的单链表的完整程序。

  #include

  #include/*包含动态内存分配函数的头文件*/

  #defineN10/*N为人数*/

  typedefstructnode

  {

  charname[20];

  structnode*link;

  }stud;

  stud*creat(intn)/*建立单链表的函数,形参n为人数*/

  {

  stud*p,*h,*s;/**h保存表头结点的指针,*p指向当前结点的前一个结点,*s指向当前结点*/

  inti;/*计数器*/

  if((h=(stud*)malloc(sizeof(stud)))==NULL)/*分配空间并检测*/

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  h->name[0]='\0';/*把表头结点的数据域置空*/

  h->link=NULL;/*把表头结点的链域置空*/

  p=h;/*p指向表头结点*/

  for(i=0;i

  {

  if((s=(stud*)malloc(sizeof(stud)))==NULL)/*分配新存储空间并检测*/

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  p->link=s;/*把s的地址赋给p所指向的结点的链域,这样就把p和s所指向的结点连接起来了*/

  printf("请输入第%d个人的姓名",i1);

  scanf("%s",s->name);/*在当前结点s的数据域中存储姓名*/

  s->link=NULL;

  p=s;

  }

  return(h);

  }

  main()

  {

  intnumber;/*保存人数的变量*/

  stud*head;/*head是保存单链表的表头结点地址的指针*/

  number=N;

  head=creat(number);/*把所新建的单链表表头地址赋给head*/

  }

  这样就写好了一个可以建立包含N个人姓名的单链表了。

  写动态内存分配的程序应注意,请尽量对分配是否成功进行检测。

二、单链表的基本运算

  建立了一个单链表之后,如果要进行一些如插入、删除等操作该怎么办?

所以还须掌握一些单链表的基本算法,来实现这些操作。

单链表的基本运算包括:

查找、插入和删除。

下面我们就一一介绍这三种基本运算的算法,并结合我们建立单链表的例子写出相应的程序。

  1、查找

  对单链表进行查找的思路为:

对单链表的结点依次扫描,检测其数据域是否是我们所要查好的值,若是返回该结点的指针,否则返回NULL。

  因为在单链表的链域中包含了后继结点的存储地址,所以当我们实现的时候,只要知道该单链表的头指针,即可依次对每个结点的数据域进行检测。

  以下是应用查找算法的一个例子:

  #include

  #include

  #include/*包含一些字符串处理函数的头文件*/

  #defineN10

  typedefstructnode

  {

  charname[20];

  structnode*link;

  }stud;

  stud*creat(intn)/*建立链表的函数*/

  {

  stud*p,*h,*s;

  inti;

  if((h=(stud*)malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  h->name[0]='\0';

  h->link=NULL;

  p=h;

  for(i=0;i

  {

  if((s=(stud*)malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  p->link=s;

  printf("请输入第%d个人的姓名",i1);

  scanf("%s",s->name);

  s->link=NULL;

  p=s;

  }

  return(h);

  }

  stud*search(stud*h,char*x)/*查找链表的函数,其中h指针是链表的表头指针,x指针是要查找的人的姓名*/

  {

  stud*p;/*当前指针,指向要与所查找的姓名比较的结点*/

  char*y;/*保存结点数据域内姓名的指针*/

  p=h->link;

  while(p!

=NULL)

  {

  y=p->name;

  if(strcmp(y,x)==0)/*把数据域里的姓名与所要查找的姓名比较,若相同则返回0,即条件成立*/

  return(p);/*返回与所要查找结点的地址*/

  elsep=p->link;

  }

  if(p==NULL)

  printf("没有查找到该数据!

");

  }

  main()

  {

  intnumber;

  charfullname[20];

  stud*head,*searchpoint;/*head是表头指针,searchpoint是保存符合条件的结点地址的指针*/

  number=N;

  head=creat(number);

  printf("请输入你要查找的人的姓名:

");

  scanf("%s",fullname);

  searchpoint=search(head,fullname);/*调用查找函数,并把结果赋给searchpoint指针*/

  }

2、插入(后插)

  假设在一个单链表中存在2个连续结点p、q(其中p为q的直接前驱),若我们需要在p、q之间插入一个新结点s,那么我们必须先为s分配空间并赋值,然后使p的链域存储s的地址,s的链域存储q的地址即可。

(p->link=s;s->link=q),这样就完成了插入操作。

  下例是应用插入算法的一个例子:

  #include

  #include

  #include

  #defineN10

  typedefstructnode

  {

  charname[20];

  structnode*link;

  }stud;

  stud*creat(intn)/*建立单链表的函数*/

  {

  stud*p,*h,*s;

  inti;

  if((h=(stud*)malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  h->name[0]='\0';

  h->link=NULL;

  p=h;

  for(i=0;i

  {

  if((s=(stud*)malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  p->link=s;

  printf("请输入第%d个人的姓名:

",i1);

  scanf("%s",s->name);

  s->link=NULL;

  p=s;

  }

  return(h);

  }

  stud*search(stud*h,char*x)/*查找函数*/

  {

  stud*p;

  char*y;

  p=h->link;

  while(p!

=NULL)

  {

  y=p->name;

  if(strcmp(y,x)==0)

  return(p);

  elsep=p->link;

  }

  if(p==NULL)

  printf("没有查找到该数据!

");

  }

  voidinsert(stud*p)/*插入函数,在指针p后插入*/

  {

  charstuname[20];

  stud*s;/*指针s是保存新结点地址的*/

  if((s=(stud*)malloc(sizeof(stud)))==NULL)

  {

  printf("不能分配内存空间!

");

  exit(0);

  }

  printf("请输入你要插入的人的姓名:

");

  scanf("%s",stuname);

  strcpy(s->name,stuname);/*把指针stuname所指向的数组元素拷贝给新结点的数据域*/

  s->link=p->link;/*把新结点的链域指向原来p结点的后继结点*/

  p->link=s;/*p结点的链域指向新结点*/

  }

  main()

  {

  intnumber;

  charfullname[20];/*保存输入的要查找的人的姓名*/

  stud*head,*searchpoint;

  number=N;

  head=creat(number);/*建立新链表并返回表头指针*/

  printf("请输入你要查找的人的姓名:

");

  scanf("%s",fullname);

  searchpoint=search(head,fullname);/*查找并返回查找到的结点指针*/

  insert(searchpoint);/*调用插入函数*/

  }

3、删除

  假如我们已经知道了要删除的结点p的位置,那么要删除p结点时只要令p结点的前驱结点的链域由存储p结点的地址该为存储p的后继结点的地址,并回收p结点即可。

  以下便是应用删除算法的实例:

  #include

  #include

  #include

  #defineN10

  typedefstructnode

  {

  charname[20];

  structnode*link;

  }

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

当前位置:首页 > 经管营销 > 财务管理

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

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