ZZU的学弟学妹们不要抄作业哦~(`Д´)
一、实验目的
1.掌握线性表的链式存储结构的表示和实现方法。
2.掌握链表基本操作的算法实现。
二、实验内容
1.建立单链表,并在单链表上实现插入、删除和查找操作(验证性内容)。
2.计算已知一个单链表中数据域值为一个指定值x的结点个数(应用性设计内容)。
3.建立双向循环链表,并在双向循环链表上实现插入、删除和查找操作(选做内容)。
三、实验要求
1.建立单链表,并在单链表上实现插入、删除和查找操作。
编程实现如下功能:
(1)根据输入的一系列整数,以0标志结束,用头插法建立单链表,并输出单链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在单链表的第i个元素之前插入一个值为x的元素,并输出插入后的单链表中各元素值。
(3)删除单链表中第i个元素,并输出删除后的单链表中各元素值。
(4)在单链表中查找第i个元素,如果查找成功,则显示该元素的值,否则显示该元素不存在。
2.计算已知一个单链表中数据域值为一个指定值x的结点个数。
⑴ 从键盘输入若干个整数,以此序列为顺序建立一个不带头结点的单链表;
⑵ 输出此单链表中的各个数据元素值;
⑶ 给定一个x的具体整数值,计算并返回此单链表中数据域值为x的结点个数值。
3.建立双向循环链表,并在双向循环链表上实现插入、删除和查找操作。
(1)输入链表的长度和各元素的值,用尾插法建立双向循环链表,并输出链表中各元素值,观察输入的内容与输出的内容是否一致。
(2)在双向循环链表的第i个元素之前插入一个值为x的元素,并输出插入后的链表中各元素值。
(3)删除双向循环链表中第i个元素,并输出删除后的链表中各元素值。
(4)在双向循环链表中查找值为x元素,如果查找成功,则显示该元素在链表中的位置,否则显示该元素不存在。
四、详细程序清单
//1.单链表
#include
#include
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
LinkList head,k;
void Show(LinkList t)//显示
{
printf("当前链表元素为:");
t=t->next;
while(t!=NULL)
{
printf("%d ",t->data);
t=t->next;
}
printf("\n");
}
void CreateHead(LinkList &L)//头插法创建单链表
{
head=(LinkList)malloc(sizeof(LNode));
head->next=NULL;
head->data=NULL;
LinkList p,t;
int x;
t=head;
printf("请输入数值,以0结束\n");
while(~scanf("%d",&x),x)
{
p=(LinkList)malloc(sizeof(LNode));
p->data=x;
p->next=t->next;
t->next=p;
}
}
void CreateTail(LinkList &L)//尾插法创建单链表并显示
{
k=(LinkList)malloc(sizeof(LNode));
k->next=NULL;
k->data=NULL;
LinkList last,t,s;
int x;
last=k;
s=k;
printf("请输入数值,以0结束\n");
while(~scanf("%d",&x),x)
{
t=(LinkList)malloc(sizeof(LNode));
t->data=x;
t->next=NULL;
if(head==NULL){head=t;last=t;}
else{last->next=t;last=t;}
}
}
int Insert(LinkList &L,int i,int e)//插入
{
LinkList t,p;
int j=1;
t=head;
if(i<1){printf("插入错误\n");return 0;}
if(i==1) //插入位置在表头
{
p=(LinkList)malloc(sizeof(LNode));
p->data=e;
p->next=t->next;
head->next=p;
printf("插入成功\n");
return 0;
}
while(j<i-1&&L)
{
t=t->next;
j++;
if(t==NULL)
{
printf("插入错误\n");
return 0;
}
}
//插在非表头
t=t->next;
p=(LinkList)malloc(sizeof(LNode));
p->data=e;
p->next=t->next;
t->next=p;
printf("插入成功\n");
}
int Delete(LinkList &L,int i)//删除
{
LinkList p,t;
int j=0;
p=head;
if(i<1){printf("删除失败\n");return 0;}
while(j<i-1&&L)
{
p=p->next;
j++;
if(p==NULL)
{
printf("删除失败\n");
return 0;
}
}
t=p->next;
p->next=t->next;
printf("删除成功\n");
free(t);
}
int Secrch(LinkList &L,int i)//查找
{
LinkList p;
int j=0,e;
p=head;
if(i<1){printf("查找失败,该元素不存在\n");return 0;}
while(j<i&&L)
{
p=p->next;
j++;
if(p==NULL)
{
printf("查找失败,该元素不存在\n");
return 0;
}
}
e=p->data;
printf("查找成功,第%d个元素为%d\n",i,e);
}
void Calculate(LinkList &L,int i)
{
LinkList p;
p=k;
int count=0;
while(p->next!=NULL)
{
if(i==p->data) count++;
p=p->next;
}
printf("元素%d有%d个\n",i,count);
}
int main()
{
LinkList L;
int select,i,e;
while(1)
{
printf("1.头插法建表 \t2.尾插法建表 \t3.插入 \t4.删除 \t5.查找 \t6.统计\n");
scanf("%d",&select);
switch(select)
{
case 1:
CreateHead(L);
Show(head);
break;
case 2:
CreateTail(L);
Show(k);
break;
case 3:
printf("输入位置和要插入的元素\n");
scanf("%d%d",&i,&e);
Insert(L,i,e);
Show(head);
break;
case 4:
printf("输入要删除的元素的位置\n");
scanf("%d",&i);
Delete(L,i);
Show(head);
break;
case 5:
printf("输入要查找的元素的位置\n");
scanf("%d",&i);
Secrch(L,i);
break;
case 6:
printf("输入要统计的元素值\n");
scanf("%d",&i);
Calculate(L,i);
break;
case 7:
return 0;
default:
printf("输入错误\n");
break;
}
}
return 0;
}
//2.双向循环链表 DC:Double Circular
#include
#include
typedef struct DCLNode{
int data;
struct DCLNode *prior;
struct DCLNode *next;
}DCLNode,*DCLinkList;
DCLinkList w;//尾
void Create(DCLinkList &L,int n)
{
DCLinkList p,t;
int x;
t=L;
scanf("%d",&x);
while(1)
{
n--;
if(!n){t=p;break;}
p=(DCLinkList)malloc(sizeof(DCLNode));
t->data=x;
t->next=p;
p->prior=t;
scanf("%d",&x);
p->data=x;
t=p;
}
L->prior=t;
t->next=L;
w=t;
}
void Show(DCLinkList L)
{
DCLinkList p;
printf("当前链表元素为:");
for(p=L;p->next!=L;p=p->next)
{
printf("%d ",p->data);
}
printf("%d ",p->data);
printf("\n");
}
int Insert(DCLinkList &L,int i,int e)//插入
{
DCLinkList t,p;
int j=1;
t=w;
if(i<1){printf("插入错误\n");return 0;}
while(j<=i-1)
{
t=t->next;
j++;
}
p=(DCLinkList)malloc(sizeof(DCLNode));
p->data=e;
p->next=t->next;
t->next=p;
p->prior=t;
printf("插入成功\n");
}
int Delete(DCLinkList &L,int i)//删除
{
DCLinkList p,t;
int j=0;
p=w;
if(i<1){printf("删除失败\n");return 0;}
while(j<i-1)
{
p=p->next;
j++;
}
t=p->next;
p->next=t->next;
t->next->prior=p;
printf("删除成功\n");
free(t);
}
int Secrch(DCLinkList &L,int e)//查找
{
DCLinkList p;
int j=1;
p=w->next;
while(1)
{
if(p->data==e){printf("查找成功,%d元素的位置为%d\n",e,j);return 0;}
if(p==w){printf("查找失败,该元素不存在\n");return 0;}
p=p->next;
j++;
}
}
int main()
{
DCLinkList L;
int select,i,e;
L=(DCLinkList)malloc(sizeof(DCLNode));
L->data=NULL;
L->next=L;
L->prior=L;
while(1)
{
printf("1.建表 \t2.插入 \t3.删除 \t4.查找\n");
scanf("%d",&select);
switch(select)
{
case 1:
printf("输入链表长度\n");
scanf("%d",&i);
printf("输入各元素的值\n");
Create(L,i);
Show(w->next);
break;
case 2:
printf("输入位置和要插入的元素\n");
scanf("%d%d",&i,&e);
Insert(L,i,e);
Show(w->next);
break;
case 3:
printf("输入要删除的元素的位置\n");
scanf("%d",&i);
Delete(L,i);
Show(w->next);
break;
case 4:
printf("输入要查找的元素\n");
scanf("%d",&i);
Secrch(L,i);
break;
case 5:
return 0;
default:
printf("输入错误\n");
break;
}
}
return 0;
}
六、实验心得体会
1.进行除Create操作外的操作时,单链表的head最好不要变;
2.上课的时候没有理解为什么head指针的data要为NULL,经过实际操作后发现了头指针为空时,便于遍历、插入、查找等操作;
3.双向循环链表中的节点都不为空,在遍历等操作的时候和单链表有所不同,可以从尾指针->next开始;
5.错误很多,调试很烦,要有耐心。