3数据结构实验链表答案.docx
《3数据结构实验链表答案.docx》由会员分享,可在线阅读,更多相关《3数据结构实验链表答案.docx(18页珍藏版)》请在冰豆网上搜索。
3数据结构实验链表答案
实验报告
院(系):
信息科学与技术学院课程名称:
数据结构日期:
班级
学号
实验室
专业
姓名
计算机号
实验名称
线性链表的运算
成绩评定
所用软件
VC或TC
教师签名
实
验
目
的
1.掌握线性链表的基本概念
2.掌握线性链表的建立、插入和删除等方法。
3.掌握线性链表的基本算法。
总
结
一、程序:
#include"stdio.h"
#include"stdlib.h"
typedefcharelemtype;
typedefstructnode{
elemtypedata;
structnode*next;
}NODE,*NODEPTR;
NODEPTRcreatelistf()
{charch;
NODEPTRhead;
NODE*p;
head=(NODEPTR)malloc(sizeof(NODE));
head->next=0;
ch=getchar();
while(ch!
='\n')
{p=(NODE*)malloc(sizeof(NODE));
p->data=ch;
p->next=head->next;
head->next=p;
}
return(head);
intInsLinkList(NODE*p,charx)
{
NODE*s;/*定义指向结点类型的指针*/
s=(NODE*)malloc(sizeof(NODE));
/*生成新结点*/
s->data=x;
s->next=p->next;
p->next=s;
return1;
voidDelLinkList(NODE*p)
{NODE*q;
if(p->next!
=0)
{q=p->next;/*q指向p的后继结点*/
p->next=q->next;/*修改p结点的指针域*/
free(q);}/*删除并释放结点*/
NODE*lbcz(NODE*h,intx)
{NODE*p;
p=h;
while(p!
=0&&p->data!
=x)p=p->next;
return(p);
voidprintlink(NODE*h)
p=h->next;
printf("\n");
{printf("%c",p->data);
p=p->next;
voidmain()
{NODE*h,*p;
charx;
printf("\n头插法建立单链表,应包含字符a,以回车作为结束符\n");
h=createlistf();
printf("\n建立的单链表为\n");
printlink(h);
printf("\n在链表中查找字符a\n");
p=lbcz(h,'a');
printf("\n将字符k插入到字符a后面\n");
InsLinkList(p,'k');
printf("\n插入字符后的链表为\n");
printf("\n输入链表中被删除字符的前一个字符\n");
scanf("%c",&x);
p=lbcz(h,x);
printf("\n删除该字符后的一个字符\n");
DelLinkList(p);
printf("\n删除字符后的链表为\n");
二、源代码以及输入数据输出结果为:
typedefintelemtype;
{intch;
scanf("%d",&ch);
intInsLinkList(NODE*h,intx)
NODE*s,*q,*p;/*定义指向结点类型的指针*/
p=h;q=p;
while(p->next!
=NULL&&p->data{q=p;p=p->next;}s=(NODE*)malloc(sizeof(NODE));/*生成新结点*/s->data=x;s->next=q->next;q->next=s;return1;}voidprintlink(NODE*h){NODE*p;p=h->next;printf("\n");while(p!=0){printf("%d",p->data);p=p->next;}printf("\n");}voidmain(){NODE*h;printf("用头插法建升序链表,注意输入数字的顺序与得到顺序相反,以0作为结束\n");h=createlistf();printf("建立的链表为");printlink(h);InsLinkList(h,55);printf("插入后的链表为");printlink(h);}运行情况为:三、已知单链表L,写一算法,删除其重复结点。算法思路:用指针p指向第一个数据结点,从它的后继结点开始到表的结束,找与其值相同的结点并删除之;p指向下一个;依此类推,p指向最后结点时算法结束。源程序如下:#include"stdio.h"#include"stdlib.h"typedefcharelemtype;typedefstructnode{elemtypedata;structnode*next;}NODE,*NODEPTR;NODEPTRcreatelistf(){charch;NODEPTRhead;NODE*p;printf("头插法建立链表\n");printf("请输入字符串,以回车键结束:");head=(NODEPTR)malloc(sizeof(NODE));head->next=0;ch=getchar();while(ch!='\n'){p=(NODE*)malloc(sizeof(NODE));p->data=ch;p->next=head->next;head->next=p;ch=getchar();}return(head);}voiddeLinkList(NODEPTRH){NODE*p,*q,*r;p=H->next;//p指向第一个结点while(p!=NULL){q=p;while(q->next!=NULL)//从*p的后继开始找重复结点{if(q->next->data==p->data){r=q->next;//找到重复结点,用r指向,删除*rq->next=r->next;free(r);}elseq=q->next;}//while(q->next)p=p->next;//p指向下一个,继续}//while(p->next)}voidplink(NODE*h){NODE*p;p=h->next;printf("\n");while(p!=NULL){printf("%c",p->data);p=p->next;}printf("\n");}voidmain(){NODE*h;h=createlistf();printf("建立的链表为");plink(h);deLinkList(h);printf("删除了重复结点的链表为");plink(h);}四、设有两个单链表A、B,其中元素递增有序,编写算法将A、B归并成一个按元素值递减(允许有相同值)有序的链表C,要求用A、B中的原结点形成,不能重新申请结点。#include"stdio.h"#include"stdlib.h"typedefintelemtype;typedefstructnode{elemtypedata;structnode*next;}NODE,*NODEPTR;NODEPTRcreatelistf()//使用尾插法建立线性链表{intx;NODEPTRhead,r;NODE*p;head=(NODEPTR)malloc(sizeof(NODE));head->next=0;r=head;//r作为尾指针printf("请输入整型数据到线性表中,以-1作为结束符\n");scanf("%d",&x);while(x!=-1)//使用-1作为输入结束符{p=(NODE*)malloc(sizeof(NODE));p->data=x;r->next=p;r=p;scanf("%d",&x);}r->next=0;return(head);}NODEPTRmerge(NODEPTRA,NODEPTRB)//线性链表的合并{NODEPTRC;NODE*p,*q,*s;p=A->next;q=B->next;C=A;//C表的头结点C->next=NULL;free(B);while(p&&q){if(p->datadata){s=p;p=p->next;}else{s=q;q=q->next;}//从原AB表上摘下较小者s->next=C->next;//插入到C表的头部C->next=s;}//whileif(p==NULL)p=q;while(p)//将剩余的结点一个个摘下插入到C表的头部*/{s=p;p=p->next;s->next=C->next;C->next=s;}returnC;}voidplink(NODE*h)//线性链表的输出{NODE*p;p=h->next;printf("\n");while(p!=0){printf("%d",p->data);p=p->next;}printf("\n");}voidmain(){NODE*a,*b;printf("建立有序线性链表a和线性链表b(升序)\n");a=createlistf();b=createlistf();printf("所建立的线性链表a和线性链表b分别为:\n");plink(a);plink(b);a=merge(a,b);printf("合并后的线性链表为:\n");plink(a);}五、已知单链表表示的线性表中含有两类的数据元素(字母字符,数字字符)。试设计算法,按结点的值将单链表拆分成两个循环链表,分别只含有数字或字母。要求:利用原表中的结点空间作为这两个表的结点空间,头结点可另开辟空间。#include"stdio.h"#include"stdlib.h"typedefcharelemtype;typedefstructnode{elemtypedata;structnode*next;}NODE,*NODEPTR;NODEPTRcreatelistf()//使用尾插法建立线性单链表{charx;NODEPTRhead,r;NODE*p;head=(NODEPTR)malloc(sizeof(NODE));head->next=0;r=head;//r作为尾指针printf("请输入字符到线性表中,以回车作为结束符\n");x=getchar();while(x!='\n')//使用回车作为输入结束符{p=(NODE*)malloc(sizeof(NODE));p->data=x;r->next=p;r=p;x=getchar();}r->next=NULL;return(head);}voidplink(NODE*a)//单链表的输出{NODE*p;p=a->next;printf("\n");while(p!=NULL){printf("%c",p->data);p=p->next;}printf("\n");}voidplooplink(NODE*a)//循环单链表的输出{NODE*p;p=a->next;printf("\n");while(p!=a){printf("%c",p->data);p=p->next;}printf("\n");}voidchaifen(NODEPTRh)//线性链表的拆分{NODEPTRa,b;NODE*ar,*br,*p;if(h->next==NULL)return;a=(NODEPTR)malloc(sizeof(NODE));a->next=a;//申请a头结点ar=a;b=(NODEPTR)malloc(sizeof(NODE));//申请b头结点b->next=b;br=b;p=h->next;while(p!=NULL){if(p->data>='0'&&p->data<='9'){ar->next=p;ar=ar->next;}else{br->next=p;br=br->next;}p=p->next;}ar->next=a;br->next=b;printf("拆分后的线性链表为:\n");plooplink(a);plooplink(b);printf("\n");}voidmain(){NODE*a;printf("建立线性链表a\n");a=createlistf();printf("所建立的线性链表a为:\n");plink(a);printf("对线性链表进行拆分\n");chaifen(a);}用参数传递方式:/*已知单循环链表表示的线性表中含有两类的数据元素(字母字符,数字字符)。试设计算法,按结点的值将单链表拆分成两个循环链表,分别只含有数字或字母。要求:利用原表中的结点空间作为这两个表的结点空间,头结点可另开辟空间。*/#include"stdio.h"#include"stdlib.h"#defineNULL0typedefcharelemtype;typedefstructnode{elemtypedata;structnode*next;}NODE,*NODEPTR;NODEPTRcreatelistf()//头插法建立循环单链表{charch;NODEPTRhead;NODE*p;head=(NODEPTR)malloc(sizeof(NODE));head->next=head;//建立循环空链表ch=getchar();while(ch!='\n'){p=(NODE*)malloc(sizeof(NODE));p->data=ch;p->next=head->next;head->next=p;ch=getchar();}return(head);}voidchaifen(NODEPTRh,NODEPTR*a,NODEPTR*b)//线性链表的拆分{NODE*ar,*br,*p;if(h->next==h)return;//空表返回(*a)=(NODEPTR)malloc(sizeof(NODE));//得到数字字符的空链表a(*a)->next=*a;ar=*a;//指针ar指向数字字符链表a(*b)=(NODEPTR)malloc(sizeof(NODE));//得到字母字符的空链表(*b)->next=*a;br=*b;//指针br指向字母字符链表abp=h->next;while(p!=h){if(p->data>='0'&&p->data<='9')//是数字字符,则加入到链表a{ar->next=p;ar=ar->next;}else{br->next=p;br=br->next;}//否则加入到链表bp=p->next;}ar->next=*a;br->next=*b;}voidplink(NODE*h)//输出循环单链表{NODE*p;p=h->next;printf("\n");while(p!=h){printf("%c",p->data);p=p->next;}printf("\n");}voidmain(){NODE*a;NODEPTRb,c;a=createlistf();printf("头插法建立的循环单链表a为:");plink(a);printf("\n");chaifen(a,&b,&c);printf("拆分后的数字字符线性链表为:");plink(b);printf("拆分后的字母字符线性链表为:");plink(c);}
{q=p;p=p->next;}
s->next=q->next;
q->next=s;
{printf("%d",p->data);
{NODE*h;
printf("用头插法建升序链表,注意输入数字的顺序与得到顺序相反,以0作为结束\n");
printf("建立的链表为");
InsLinkList(h,55);
printf("插入后的链表为");
运行情况为:
三、已知单链表L,写一算法,删除其重复结点。
算法思路:
用指针p指向第一个数据结点,从它的后继结点开始到表的结束,找与其值相同的结点并删除之;p指向下一个;依此类推,p指向最后结点时算法结束。
源程序如下:
printf("头插法建立链表\n");
printf("请输入字符串,以回车键结束:
");
voiddeLinkList(NODEPTRH)
{NODE*p,*q,*r;
p=H->next;//p指向第一个结点
=NULL)
{q=p;
while(q->next!
=NULL)//从*p的后继开始找重复结点
{if(q->next->data==p->data)
{r=q->next;//找到重复结点,用r指向,删除*r
q->next=r->next;
free(r);
elseq=q->next;
}//while(q->next)
p=p->next;//p指向下一个,继续
}//while(p->next)
voidplink(NODE*h)
plink(h);
deLinkList(h);
printf("删除了重复结点的链表为");
四、设有两个单链表A、B,其中元素递增有序,编写算法将A、B归并成一个按元素值递减(允许有相同值)有序的链表C,要求用A、B中的原结点形成,不能重新申请结点。
typedefstructnode
NODEPTRcreatelistf()//使用尾插法建立线性链表
{intx;
NODEPTRhead,r;
r=head;//r作为尾指针
printf("请输入整型数据到线性表中,以-1作为结束符\n");
scanf("%d",&x);
while(x!
=-1)//使用-1作为输入结束符
p->data=x;
r->next=p;
r=p;
r->next=0;
NODEPTRmerge(NODEPTRA,NODEPTRB)//线性链表的合并
{NODEPTRC;
NODE*p,*q,*s;
p=A->next;q=B->next;
C=A;//C表的头结点
C->next=NULL;
free(B);
while(p&&q)
{if(p->datadata)
{s=p;p=p->next;}
else
{s=q;q=q->next;}//从原AB表上摘下较小者
s->next=C->next;//插入到C表的头部
C->next=s;
}//while
if(p==NULL)p=q;
while(p)//将剩余的结点一个个摘下插入到C表的头部*/
{s=p;p=p->next;
s->next=C->next;
returnC;
voidplink(NODE*h)//线性链表的输出
{NODE*a,*b;
printf("建立有序线性链表a和线性链表b(升序)\n");
a=createlistf();
b=createlistf();
printf("所建立的线性链表a和线性链表b分别为:
\n");
plink(a);
plink(b);
a=merge(a,b);
printf("合并后的线性链表为:
五、已知单链表表示的线性表中含有两类的数据元素(字母字符,数字字符)。
试设计算法,按结点的值将单链表拆分成两个循环链表,分别只含有数字或字母。
要求:
利用原表中的结点空间作为这两个表的结点空间,头结点可另开辟空间。
NODEPTRcreatelistf()//使用尾插法建立线性单链表
{charx;
printf("请输入字符到线性表中,以回车作为结束符\n");
x=getchar();
='\n')//使用回车作为输入结束符
r->next=NULL;
voidplink(NODE*a)//单链表的输出
p=a->next;
voidplooplink(NODE*a)//循环单链表的输出
=a)
voidchaifen(NODEPTRh)//线性链表的拆分
{NODEPTRa,b;
NODE*ar,*br,*p;
if(h->next==NULL)return;
a=(NODEPTR)malloc(sizeof(NODE));
a->next=a;//申请a头结点
ar=a;
b=(NODEPTR)malloc(sizeof(NODE));//申请b头结点
b->next=b;
br=b;
{if(p->data>='0'&&p->data<='9')
{ar->next=p;ar=ar->next;}
{br->next=p;br=br->next;}
ar->next=a;
br->next=b;
printf("拆分后的线性链表为:
plooplink(a);
plooplink(b);
{NODE*a;
printf("建立线性链表a\n");
printf("所建立的线性链表a为:
printf("对线性链表进行拆分\n");
chaifen(a);
用参数传递方式:
/*已知单循环链表表示的线性表中含有两类的数据元素(字母字符,数字字符)。
*/
#defineNULL0
NODEPTRcreatelistf()//头插法建立循环单链表
charch;
head->next=head;//建立循环空链表
voidchaifen(NODEPTRh,NODEPTR*a,NODEPTR*b)//线性链表的拆分
{NODE*ar,*br,*p;
if(h->next==h)return;//空表返回
(*a)=(NODEPTR)malloc(sizeof(NODE));//得到数字字符的空链表a
(*a)->next=*a;
ar=*a;//指针ar指向数字字符链表a
(*b)=(NODEPTR)malloc(sizeof(NODE));//得到字母字符的空链表
(*b)->next=*a;
br=*b;//指针br指向字母字符链表ab
=h)
{if(p->data>='0'&&p->data<='9')//是数字字符,则加入到链表a
{br->next=p;br=br->next;}//否则加入到链表b
ar->next=*a;
br->next=*b;
voidplink(NODE*h)//输出循环单链表
NODEPTRb,c;
printf("头插法建立的循环单链表a为:
chaifen(a,&b,&c);
printf("拆分后的数字字符线性链表为:
printf("拆分后的字母字符线性链表为:
plink(c);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1