C语言链表的建立和基本运算.docx

上传人:b****4 文档编号:4032972 上传时间:2022-11-27 格式:DOCX 页数:19 大小:19.39KB
下载 相关 举报
C语言链表的建立和基本运算.docx_第1页
第1页 / 共19页
C语言链表的建立和基本运算.docx_第2页
第2页 / 共19页
C语言链表的建立和基本运算.docx_第3页
第3页 / 共19页
C语言链表的建立和基本运算.docx_第4页
第4页 / 共19页
C语言链表的建立和基本运算.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

C语言链表的建立和基本运算.docx

《C语言链表的建立和基本运算.docx》由会员分享,可在线阅读,更多相关《C语言链表的建立和基本运算.docx(19页珍藏版)》请在冰豆网上搜索。

C语言链表的建立和基本运算.docx

C语言链表的建立和基本运算

malloc函数

malloc函数的原型为:

void*malloc(unsignedintsize)

其作用是在内存的动态存储区中分配一个长度为size的连续空间。

其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。

还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。

所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。

下例

是一个动态分配的程序:

#include

#include

main()

{

intcount,*array;/*count是一个计数器,array是一个整型指针,也可以理解为指向一个整型数组的首地址*/

if((array(int*)malloc(10*sizeof(int)))==NULL)

{

printf("不能成功分配存储空间。

");

exit

(1);

}

for(count=0;count〈10;count++)/*给数组赋值*/

array[count]=count;

for(count=0;count〈10;count++)/*打印数组元素*/

printf("%2d",array[count]);

}

上例中动态分配了10个整型存储区域,然后进行赋值并打印。

例中if((array(int*)malloc(10*sizeof(int)))==NULL)语句可以分为以下几步:

1)分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针

2)把此整型指针地址赋给array

3)检测返回值是否为NULL

一、单链表的建立

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

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

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

我们先讲讲单链表。

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

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

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个人的姓名",i+1);

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个人的姓名",i+1);

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个人的姓名:

",i+1);

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);/*调用插入函数*/

}

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

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

#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个人的姓名",i+1);

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("没有查找到该数据!

");

}

stud*search2(stud*h,char*x)/*另一个查找函数,返回的是上一个查找函数的直接前驱结点的指针,*/

/*h为表头指针,x为指向要查找的姓名的指针*/

/*其实此函数的算法与上面的查找算法是一样的,只是多了一个指针s,并且s总是指向指针p所指向的结点的直接前驱,*/

/*结果返回s即是要查找的结点的前一个结点*/

{

stud*p,*s;

char*y;

p=h->link;

s=h;

while(p!

=NULL)

{

y=p->name;

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

return(s);

else

{

p=p->link;

s=s->link;

}

}

if(p==NULL)

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

");

}

voiddel(stud*x,stud*y)/*删除函数,其中y为要删除的结点的指针,x为要删除的结点的前一个结点的指针*/

{

stud*s;

s=y;

x->link=y->link;

free(s);

}

main()

{

intnumber;

charfullname[20];

stud*head,*searchpoint,*forepoint;

number=N;

head=creat(number);

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

");

scanf("%s",fullname);

searchpoint=search(head,fullname);

forepoint=search2(head,fullname);

del(forepoint,searchpoint);

//创建data型结构,为生成链表做准备

structdata

{

intvalue;

data*next;

};

//对链表进行排列的函数

voidline(data*p,intn)

{inttemp,i,j;

data*tp;

for(i=0;i

for(j=0,tp=p;jnext)

{if(tp->value>tp->next->value)

{temp=tp->next->value;

tp->next->value=tp->value;

tp->value=temp;

}

}

}

以上是冒泡法对链表排序的例子;

//输出答案的函数

voidanswer(data*p)

{

while(p!

=NULL)

{

cout<value<

p=p->next;

}

}

以上是遍历链表的函数p是链表的头指针

在这里列举了一个应用单链表基本算法的综合程序。

#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个人的姓名",i+1);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("没有查找到该数据!

");

}

stud*search2(stud*h,char*x)

{

stud*p,*s;

char*y;

p=h->link;

s=h;

while(p!

=NULL)

{

y=p->name;

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

return(s);

else

{

p=p->link;

s=s->link;

}

}

if(p==NULL)

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

");

}

voidinsert(stud*p)

{

charstuname[20];

stud*s;

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

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

");

exit(0);

}

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

");scanf("%s",stuname);

strcpy(s->name,stuname);

s->link=p->link;

p->link=s;

voiddel(stud*x,stud*y)

{

stud*s;

s=y;

x->link=y->link;

free(s);

}

voidprint(stud*h)

{

stud*p;

p=h->link;

printf("数据信息为:

\n");

while(p!

=NULL)

{

printf("%s",&*(p->name));

p=p->link;

}

}

voidquit()

{

exit(0);

}

voidmenu(void)

{

clrscr();

printf("\t\t\t单链表C语言实现实例\n");

printf("\t\t|————————————————|\n");printf("\t\t||\n");

printf("\t\t|[1]建立新表|\n");

printf("\t\t|[2]查找数据|\n");

printf("\t\t|[3]插入数据|\n");

printf("\t\t|[4]删除数据|\n");

printf("\t\t|[5]打印数据|\n");

printf("\t\t|[6]退出|\n");

printf("\t\t||\n");

printf("\t\t|如未建立新表,请先建立!

|\n");

printf("\t\t||\n");

printf("\t\t|————————————————|\n");printf("\t\t请输入你的选项(1-6):

");

main()

{

intchoose;

stud*head,*searchpoint,*forepoint;

charfullname[20];

while

(1)

{

menu();

scanf("%d",&choose);

switch(choose)

{

case1:

head=creat(N);

break;

case2:

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

");

scanf("%s",fullname);

searchpoint=search(head,fullname);

printf("你所查找的人的姓名为:

%s",*&searchpoint->name);printf("\n按回车键回到主菜单。

");

getchar();getchar();

break;

case3:

printf("输入你要在哪个人后面插入:

");

scanf("%s",fullname);

searchpoint=search(head,fullname);

printf("你所查找的人的姓名为:

%s",*&searchpoint->name);insert(searchpoint);

print(head);

printf("\n按回车键回到主菜单。

");

getchar();getchar();

break;

case4:

print(head);

printf("\n输入你所要删除的人的姓名:

");

scanf("%s",fullname);

searchpoint=search(head,fullname);

forepoint=search2(head,fulln

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

当前位置:首页 > 农林牧渔 > 林学

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

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