数据结构实验399XXX.docx
《数据结构实验399XXX.docx》由会员分享,可在线阅读,更多相关《数据结构实验399XXX.docx(34页珍藏版)》请在冰豆网上搜索。
![数据结构实验399XXX.docx](https://file1.bdocx.com/fileroot1/2022-11/24/a0d9a032-d0cb-4879-8c27-fb556c8d75f4/a0d9a032-d0cb-4879-8c27-fb556c8d75f41.gif)
数据结构实验399XXX
《数据结构》实验报告
实验序号:
3 实验项目名称:
链式表的操作
学 号
姓 名
pmj
专业、班
实验地点
实验楼1
指导教师
实验时间
周五
一、实验目的及要求
1.通过实验理解单链表的逻辑结构;
2.通过实验掌握单链表的基本操作和具体的函数实现。
二、实验设备(环境)及要求
微型计算机;
windows操作系统;
MicrosoftVisualStudio6.0集成开发环境。
三、实验内容与步骤
1.链式表表示和实现线性表的如下:
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"ctype.h"
typedefstructnode//定义结点
{
chardata[10];//结点的数据域为字符串
structnode*next;//结点的指针域
}ListNode;
typedefListNode*LinkList;//自定义LinkList单链表类型
LinkListCreatListR1();//函数,用尾插入法建立带头结点的单链表
ListNode*LocateNode(LinkListhead,char*key);//函数,按值查找结点
voidDeleteList(LinkListhead,char*key);//函数,删除指定值的结点
voidprintlist(LinkListhead);//函数,打印链表中的所有值
voidDeleteAll(LinkListhead);//函数,删除所有结点,释放内存
//==========主函数==============
voidmain()
{
char*ch,*num;
num=newchar;
ch=newchar[10];
LinkListhead;
head=CreatListR1();//用尾插入法建立单链表,返回头指针
printlist(head);//遍历链表输出其值
printf("Deletenode(y/n):
");//输入"y"或"n"去选择是否删除结点
scanf("%s",num);
if(strcmp(num,"y")==0||strcmp(num,"Y")==0){
printf("PleaseinputDelete_data:
");
scanf("%s",ch);//输入要删除的字符串
DeleteList(head,ch);
printlist(head);
}
DeleteAll(head);//删除所有结点,释放内存
}
//==========用尾插入法建立带头结点的单链表===========
LinkListCreatListR1(void)
{
char*ch;
ch=newchar[10];
LinkListhead=(LinkList)malloc(sizeof(ListNode));//生成头结点
ListNode*s,*r,*pp;
r=head;
r->next=NULL;
printf("Input#toend");//输入"#"代表输入结束
printf("PleaseinputNode_data:
");
scanf("%s",ch);//输入各结点的字符串
while(strcmp(ch,"#")!
=0){
s=(ListNode*)malloc(sizeof(ListNode));
strcpy(s->data,ch);
r->next=s;
r=s;
r->next=NULL;
printf("Input#toend");
printf("PleaseinputNode_data:
");
scanf("%s",ch);
}
returnhead;//返回头指针
}
//==========按值查找结点,找到则返回该结点的位置,否则返回NULL==========
ListNode*LocateNode(LinkListhead,char*key)
{
ListNode*p=head->next;//从开始结点比较
while(strcmp(p->data,key)!
=0&&p)//直到p为NULL或p->data为key止
p=p->next;//扫描下一个结点
returnp;//若p=NULL则查找失败,否则p指向找到的值为key的结点
}
//==========删除带头结点的单链表中的指定结点=======
voidDeleteList(LinkListhead,char*key)
{
ListNode*p,*r,*q=head;
p=LocateNode(head,key);//按key值查找结点的
if(p==NULL){//若没有找到结点,退出
printf("positionerror");
exit(0);
}
while(q->next!
=p)//p为要删除的结点,q为p的前结点
q=q->next;
r=q->next;
q->next=r->next;
free(r);//释放结点
}
//===========打印链表=======
voidprintlist(LinkListhead)
{
ListNode*p=head->next;//从开始结点打印
while(p){
printf("%s,",p->data);
p=p->next;
}
printf("\n");
}
//==========删除所有结点,释放空间===========
voidDeleteAll(LinkListhead)
{
ListNode*p=head,*r;
while(p->next){
r=p->next;
free(p);
p=r;
}
free(p);
}
1、调试实现单链表的的相关算法;
2、改写以上程序,实现功能如下:
1)编写一个删除链表中值为x的结点的直接前趋结点的算法,若有多个值为x的结点,则删除第一个x的直接前趋结点。
2)写一个对单循环链表进行逆序输出(打印每个结点的值)的算法。
3)改写CreatListR1函数,使得链表创建时为非递减有序的单链表。
4)在算法3)生成的非递减有序的单链表中,编写一个算法,删除单链表中值相同的多余结点。
四、实验结果与数据处理
详细记录程序在调试过程中出现的问题及解决方法。
记录程序执行的结果(贴图)。
五、分析与讨论
对上机实践结果进行分析,上机的心得体会。
六、教师评语
签名:
日期:
成绩
附源程序清单:
1、
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"ctype.h"
typedefstructnode//定义结点
{
chardata[10];//结点的数据域为字符串
structnode*next;//结点的指针域
char*L;
}ListNode;
typedefListNode*LinkList;//自定义LinkList单链表类型
LinkListCreatListR1();//函数,用尾插入法建立带头结点的单链表
LinkListCreatListR();//函数,用头插入法建立带头结点的单链表
LinkListLocateNode(LinkListhead,char*key);//函数,按值查找结点
voidDeleteList(LinkListhead,char*key);//函数,删除指定值的结点
LinkListLocateBreforeNode(LinkListhead,char*key);//函数,查找指定数值的前驱结点
voidDeleteBreforeNode(LinkListhead,char*key);//函数,删除指定数值的前驱结点
voidprintlist(LinkListhead);//函数,打印链表中的所有值
voidDeleteAll(LinkListhead);//函数,删除所有结点,释放内存
//==========主函数==============
voidmain()
{
char*ch,*num;
num=newchar;
ch=newchar[10];
LinkListhead;
LinkListpm;
head=CreatListR1();//用尾插入法建立单链表,返回头指针
printlist(head);//遍历链表输出其值
printf("Deletenode(y/n):
");//输入"y"或"n"去选择是否删除结点
scanf("%s",num);
if(strcmp(num,"y")==0||strcmp(num,"Y")==0)
{
printf("PleaseinputDelete_data:
");
scanf("%s",ch);//输入要删除的字符串
DeleteList(head,ch);
printlist(head);
}
printf("输入要查找的数值");
scanf("%s",ch);
pm=LocateNode(head,ch);
printf("%s\n",pm->data);
printf("输入要删除的数值的前驱结点");
scanf("%s",ch);
DeleteBreforeNode(head,ch);
printlist(head);
printf("对单循环链表进行逆序输出\n");
head=CreatListR();//用头插入法建立单链表,返回头指针
printlist(head);
//DeleteAll(head);//删除所有结点,释放内存
}
//==========查找的指定数值的前驱结点=======
LinkListLocateBreforeNode(LinkListhead,char*key)
{
ListNode*p=head->next;//从开始结点比较
ListNode*t;//p的上一个节点指针
while(p&&strcmp(p->data,key)!
=0)//直到p为NULL或p->data为key止
{
t=p;//记录上一个节点的指针
p=p->next;//扫描下一个结点
}
returnt;//若p=NULL则查找失败,否则p指向找到的值为key的结点
}
//==========删除的指定数值的前驱结点=======
voidDeleteBreforeNode(LinkListhead,char*key)
{
ListNode*pp,*r,*q=head;
pp=LocateBreforeNode(head,key);//按key值查找结点的
if(pp==NULL)
{//若没有找到结点,退出
printf("positionerror");
exit(0);
}
while(q->next!
=pp)//p为要删除的结点,q为p的前结点
q=q->next;
r=q->next;
q->next=r->next;
free(r);//释放结点
}
//==========用尾插入法建立带头结点的单链表===========
LinkListCreatListR1(void)
{
char*ch;
ch=newchar[10];
LinkListhead=(LinkList)malloc(sizeof(ListNode));//生成头结点
ListNode*s,*r;
r=head;
r->next=NULL;
printf("Input#toend");//输入"#"代表输入结束
printf("PleaseinputNode_data:
");
scanf("%s",ch);//输入各结点的字符串
while(strcmp(ch,"#")!
=0)
{
s=(ListNode*)malloc(sizeof(ListNode));
strcpy(s->data,ch);
r->next=s;
r=s;
r->next=NULL;
//printf("Input#toend");
//printf("PleaseinputNode_data:
");
scanf("%s",ch);
}
returnhead;//返回头指针
}
//==========用头插入法建立带头结点的单链表===========
LinkListCreatListR(void)
{
LinkListhead=(LinkList)malloc(sizeof(ListNode));//生成头结点
ListNode*s,*r;
r=head;
r->next=NULL;
printf("Input#toend");//输入"#"代表输入结束
printf("PleaseinputcricleNode_data:
");//输入各结点的字符串
do//while(strcmp(s->data,"#")!
=0)
{
s=(LinkList)malloc(sizeof(ListNode));
scanf("%s",s->data);
s->next=r->next;
r->next=s;
}while(strcmp(s->data,"#")!
=0);
r->next=r->next->next;
returnhead;//返回头指针
}
//==========按值查找结点,找到则返回该结点的位置,否则返回NULL==========
LinkListLocateNode(LinkListhead,char*key)
{
ListNode*p=head->next;//从开始结点比较
while(p&&strcmp(p->data,key)!
=0)//直到p为NULL或p->data为key止
p=p->next;//扫描下一个结点
returnp;//若p=NULL则查找失败,否则p指向找到的值为key的结点
}
//==========删除带头结点的单链表中的指定结点=======
voidDeleteList(LinkListhead,char*key)
{
ListNode*p,*r,*q=head;
p=LocateNode(head,key);//按key值查找结点的
if(p==NULL)
{//若没有找到结点,退出
printf("positionerror");
exit(0);
}
while(q->next!
=p)//p为要删除的结点,q为p的前结点
q=q->next;
r=q->next;
q->next=r->next;
free(r);//释放结点
}
//===========打印链表=======
voidprintlist(LinkListhead)
{
ListNode*p=head->next;//从开始结点打印
while(p)
{
printf("%s,",p->data);
p=p->next;
}
printf("\n");
}
//==========删除所有结点,释放空间===========
voidDeleteAll(LinkListhead)
{
ListNode*p=head,*r;
while(p->next)
{
r=p->next;
free(p);
p=r;
}
free(p);
}
1).
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"ctype.h"
typedefstructnode//定义结点
{
chardata[10];//结点的数据域为字符串
structnode*next;//结点的指针域
char*L;
}ListNode;
typedefListNode*LinkList;//自定义LinkList单链表类型
LinkListCreatListR1();//函数,用尾插入法建立带头结点的单链表
LinkListCreatListR();//函数,用头插入法建立带头结点的单链表
LinkListLocateNode(LinkListhead,char*key);//函数,按值查找结点
voidDeleteList(LinkListhead,char*key);//函数,删除指定值的结点
LinkListLocateBreforeNode(LinkListhead,char*key);//函数,查找指定数值的前驱结点
voidDeleteBreforeNode(LinkListhead,char*key);//函数,删除指定数值的前驱结点
voidprintlist(LinkListhead);//函数,打印链表中的所有值
voidDeleteAll(LinkListhead);//函数,删除所有结点,释放内存
//==========主函数==============
voidmain()
{
char*ch,*num;
num=newchar;
ch=newchar[10];
LinkListhead;
LinkListpm;
head=CreatListR1();//用尾插入法建立单链表,返回头指针
printlist(head);//遍历链表输出其值
printf("Deletenode(y/n):
");//输入"y"或"n"去选择是否删除结点
scanf("%s",num);
if(strcmp(num,"y")==0||strcmp(num,"Y")==0)
{
printf("PleaseinputDelete_data:
");
scanf("%s",ch);//输入要删除的字符串
DeleteList(head,ch);
printlist(head);
}
printf("输入要查找的数值");
scanf("%s",ch);
pm=LocateNode(head,ch);
printf("%s\n",pm->data);
printf("输入要删除的数值的前驱结点");
scanf("%s",ch);
DeleteBreforeNode(head,ch);
printlist(head);
printf("对单循环链表进行逆序输出\n");
head=CreatListR();//用头插入法建立单链表,返回头指针
printlist(head);
//DeleteAll(head);//删除所有结点,释放内存
}
//==========查找的指定数值的前驱结点=======
LinkListLocateBreforeNode(LinkListhead,char*key)
{
ListNode*p=head->next;//从开始结点比较
ListNode*t;//p的上一个节点指针
while(p&&strcmp(p->data,key)!
=0)//直到p为NULL或p->data为key止
{
t=p;//记录上一个节点的指针
p=p->next;//扫描下一个结点
}
returnt;//若p=NULL则查找失败,否则p指向找到的值为key的结点
}
//==========删除的指定数值的前驱结点=======
voidDeleteBreforeNode(LinkListhead,char*key)
{
ListNode*pp,*r,*q=head;
pp=LocateBreforeNode(head,key);//按key值查找结点的
if(pp==NULL)
{//若没有找到结点,退出
printf("positionerror");
exit(0);
}
while(q->next!
=pp)//p为要删除的结点,q为p的前结点
q=q->next;
r=q->next;
q->next=r->next;
free(r);//释放结点
}
//==========用尾插入法建立带头结点的单链表===========
LinkListCreatListR1(void)
{
char*ch;
ch=newchar[10];
LinkListhead=(LinkList)malloc(sizeof(ListNode));//生成头结点
ListNode*s,*r;
r=head;
r->next=NULL;
printf("Input#toend");//输入"#"代表输入结束
printf("PleaseinputNode_data:
");
scanf("%s",ch);//输入各结点的字符串
while(strcmp(ch,"#")!
=0)
{
s=(ListNode*)malloc(sizeof(ListNode));
strcpy(s->data,ch);
r->next=s;
r=s;
r->next=NULL;
//printf("Input#toend");
//printf("PleaseinputNode_data:
");
scanf("%s",ch);
}
returnhead;//返回头指针
}
//==========用头插入法建立带头结点的单链表===========
LinkListCreatListR(void)
{
LinkListhead=(LinkList)malloc(size