双向链表实验报告概要.docx
- 文档编号:12048963
- 上传时间:2023-04-16
- 格式:DOCX
- 页数:22
- 大小:47.53KB
双向链表实验报告概要.docx
《双向链表实验报告概要.docx》由会员分享,可在线阅读,更多相关《双向链表实验报告概要.docx(22页珍藏版)》请在冰豆网上搜索。
双向链表实验报告概要
13软工转本1钱剑滨实验报告
双向链表实验报告
信息工程系13软工转本1日期2016年03月12日
姓名钱剑滨学号13131116电话
一、实验内容
编写关于双向链表操作的C语言程序,要求包含双向链表的创建(生成)、输出(遍历)、查找、任意位置插入、有顺序插入、删除、等。
二、实验步骤
1.分析操作所需思路,熟练运用单链表的各种特点。
2.编写程序,利用函数特性进行操作。
3.运行程序,纠正错误,对预测结果进行验证。
4.分析总结单链表的优缺点,并可以做到熟练掌握双向链表的各种操作。
三、设计概要
1.本实验包含了7个函数:
a)主函数main()
b)创建链表函数Listcreate()
c)数据输出函数Listprint()
d)查找数据函数Listlocate()
e)无序插入函数Listinsert_discretion()
f)有序插入函数Listinsert_order
g)删除数据函数Listdelete()
2.明确函数的功能;
a)Listcreate()创建一个可控长度的斐波那契数列的双向链表。
b)Listprint()将此链表中的数据全部输出。
c)Listlocate()查找此链表中任意位置元素的值。
d)Listinsert_discretion()向此链表的某个位置插入一组数据。
e)Listinsert_order()向数列中插入一个数,使插入后的数列任然有序
f)Listdelete()将此链表的某个位置的一组数据删除。
四、程序设计
1.函数前包含的头文件名、结点类型定义、全局变量和函数声明
#include
#include
typedefstructnumber//定义结构体
{
structnumber*prior;
intnum;
structnumber*next;
}number;
number*head;//定义全局变量头节点
intk=0;//k记录元素个数,防止溢出
/*函数声明*/
voidListcreate();//建立链表
voidListprint();//全体输出
voidListlocate();//查找
voidListinsert_discretion();//任意位置插入
voidListinsert_order();//有顺序插入
voidListdelete();//删除
2.主函数main()
voidmain()
{
intselect;
printf("1、输入斐波那契数列的个数\n");
printf("2、全部输出数列\n");
printf("3、查找定位数列的元素\n");
printf("4、添加数列元素\n");
printf("5、插入顺序数列元素\n");
printf("6、删除数列元素\n");
printf("-------------------------------------\n");
while
(1)
{
printf("请选择序号\n");
scanf("%d",&select);
switch(select)
{
case1:
Listcreate();break;//链表创建
case2:
Listprint();break;//全链表输出
case3:
Listlocate();break;//元素查找
case4:
Listinsert_discretion();break;//任意位置插入
case5:
Listinsert_order();break;//有顺序插入
case6:
Listdelete();break;//删除
default:
break;
}
}
}
3.创建链表函数Listcreate()
voidListcreate()//建立链表
{
head=(number*)malloc(sizeof(number));//开辟一个大小为number的内存空间给头节点
head->next=NULL;
head->prior=NULL;
inta=1,b=1;//a、b为斐波那契数列的前两个元素
inti;
number*q;
number*p=head;//p始终指向最后一个节点
printf("输入元素的长度\n");
scanf("%d",&i);
/*给第一个元素赋值*/
q=(number*)malloc(sizeof(number));//开辟一个大小为number的内存空间给后面节点
q->num=a;
q->next=NULL;//新开辟的节点指向NULL
p->next=q;//前一节点指向新开辟的节点
q->prior=p;//开辟的节点前驱指向p
p=p->next;//p指向新节点
i=i-1;
k=k+1;
/*给第二个元素赋值*/
q=(number*)malloc(sizeof(number));
q->num=b;
q->next=NULL;
p->next=q;
q->prior=p;
p=p->next;
i=i-1;
k=k+1;
/*给后续元素赋值*/
while(i--)
{
q=(number*)malloc(sizeof(number));
q->num=(a+b);
q->next=NULL;
p->next=q;
q->prior=p;
p=p->next;
a=a+b+b;//
b=a-b;//将a+b的值付给b;b的值付给a
a=a-b;//
k=k+1;
}
printf("链表建立成功\n");
}
4.数据输出函数Listprint()
voidListprint()//全体输出
{
number*p=head->next;
while(p!
=NULL)
{
printf("%d",p->num);
p=p->next;
}
printf("\n");
}
5.查找数据函数Listlocate()
voidListlocate()//查找
{
inti;
number*p=head;
printf("输入您要查询的元素位置\n");
scanf("%d",&i);
if((i>k)||(i<=0))
{
printf("查询的位置不存在\n");
}
else
{
while(i--)
{
p=p->next;
}
printf("所查找数为%d\n",p->num);
}
}
6.无序插入函数Listinsert_discretion()
voidListinsert_discretion()//任意位置插入
{
inti;
number*q;
number*p=head;
printf("输入您要插入哪个元素的后面\n");
scanf("%d",&i);
if((i>k)||(i<0))
{
printf("插入的位置不存在\n");
}
else
{
while(i--)
{
p=p->next;//p最后指向要插入位置的前一个节点
}
q=(number*)malloc(sizeof(number));
if(p->next==NULL)//插到末尾
{
q->next=NULL;//B的下一个元素指向空
p->next=q;//p的下一个元素指向B
q->prior=p;//B的前驱指向p
}
else
{
q->next=p->next;//B的下一个元素指向p的下一个(两个不能反)
p->next->prior=q;//p的下一个元素的前驱指向B
p->next=q;//p的下一个元素指向B
q->prior=p;//B的前驱指向p
}
printf("输入您要插入的数\n");
scanf("%d",&(q->num));
k=k+1;
}
printf("插入成功\n");
}
7.有序插入函数Listinsert_order()
voidListinsert_order()//有顺序插入
{
number*q;
number*p=head;
q=(number*)malloc(sizeof(number));
printf("输入您要插入哪个数\n");
scanf("%d",&q->num);
while(p->next)
{
if(p->next->num>=q->num)//插在第一个比数大或等于的的数前
{
q->next=p->next;
p->next->prior=q;
p->next=q;
q->prior=p;
k=k+1;
break;
}
else
{
p=p->next;
}
}
if(p->next==NULL)//插到末尾
{
q->next=NULL;
p->next=q;
q->prior=p;
k=k+1;
}
printf("插入成功\n");
}
8.删除数据函数Listdelete()
voidListdelete()//删除
{
inti;
number*q;
number*p=head;
printf("输入您要删除哪个元素\n");
scanf("%d",&i);
if((i>k)||(i<=0))
{
printf("删除的位置不存在\n");
}
else
{
while(--i)//这里是先减再判断
{
p=p->next;//p指向被删除的元素的前一个元素
}
q=p->next;//q指向被删除的元素
if(q->next==NULL)//删除最后一个元素
{
p->next=NULL;
}
else
{
p->next=q->next;//p的下一个元素指向q的下一个,即跳过被删除元素
q->next->prior=p;//q的下一个元素的前驱指向p,也跳过被删除的元素
}
free(q);//清空删除元素
k=k-1;
}
printf("删除成功\n");
}
五、程序源码
#include
#include
typedefstructnumber
{
structnumber*prior;
intnum;
structnumber*next;
}number;
number*head;//定义全局变量头节点
intk=0;//k记录元素个数,防止溢出
voidListcreate();//建立链表
voidListprint();//全体输出
voidListlocate();//查找
voidListinsert_discretion();//任意位置插入
voidListinsert_order();//有顺序插入
voidListdelete();//删除
voidmain()
{
intselect;
printf("1、输入斐波那契数列的个数\n");
printf("2、全部输出数列\n");
printf("3、查找定位数列的元素\n");
printf("4、添加数列元素\n");
printf("5、插入顺序数列元素\n");
printf("6、删除数列元素\n");
printf("-------------------------------------\n");
while
(1)
{
printf("请选择序号\n");
scanf("%d",&select);
switch(select)
{
case1:
Listcreate();break;//链表创建
case2:
Listprint();break;//全链表输出
case3:
Listlocate();break;//元素查找
case4:
Listinsert_discretion();break;//任意位置插入
case5:
Listinsert_order();break;//有顺序插入
case6:
Listdelete();break;//删除
default:
break;
}
}
}
voidListcreate()//建立链表
{
head=(number*)malloc(sizeof(number));//开辟一个大小为number的内存空间给头节点
head->next=NULL;
head->prior=NULL;
inta=1,b=1;//a、b为斐波那契数列的前两个元素
inti;
number*q;
number*p=head;//p始终指向最后一个节点
printf("输入元素的长度\n");
scanf("%d",&i);
q=(number*)malloc(sizeof(number));//开辟一个大小为number的内存空间给后面节点
q->num=a;
q->next=NULL;//新开辟的节点指向NULL
p->next=q;//前一节点指向新开辟的节点
q->prior=p;//开辟的节点前驱指向p
p=p->next;//p指向新节点
i=i-1;
k=k+1;
q=(number*)malloc(sizeof(number));
q->num=b;
q->next=NULL;
p->next=q;
q->prior=p;
p=p->next;
i=i-1;
k=k+1;
while(i--)
{
q=(number*)malloc(sizeof(number));
q->num=(a+b);
q->next=NULL;
p->next=q;
q->prior=p;
p=p->next;
a=a+b+b;//
b=a-b;//将a+b的值付给b;b的值付给a
a=a-b;//
k=k+1;
}
printf("链表建立成功\n");
}
voidListprint()//全体输出
{
number*p=head->next;
while(p!
=NULL)
{
printf("%d",p->num);
p=p->next;
}
printf("\n");
}
voidListlocate()//查找
{
inti;
number*p=head;
printf("输入您要查询的元素位置\n");
scanf("%d",&i);
if((i>k)||(i<=0))
{
printf("查询的位置不存在\n");
}
else
{
while(i--)
{
p=p->next;
}
printf("所查找数为%d\n",p->num);
}
}
voidListinsert_discretion()//任意位置插入
{
inti;
number*q;
number*p=head;
printf("输入您要插入哪个元素的后面\n");
scanf("%d",&i);
if((i>k)||(i<0))
{
printf("插入的位置不存在\n");
}
else
{
while(i--)
{
p=p->next;//p最后指向要插入位置的前一个节点
}
q=(number*)malloc(sizeof(number));
if(p->next==NULL)//插到末尾
{
q->next=NULL;//B的下一个元素指向空
p->next=q;//p的下一个元素指向B
q->prior=p;//B的前驱指向p
}
else
{
q->next=p->next;//B的下一个元素指向p的下一个(两个不能反)
p->next->prior=q;//p的下一个元素的前驱指向B
p->next=q;//p的下一个元素指向B
q->prior=p;//B的前驱指向p
}
printf("输入您要插入的数\n");
scanf("%d",&(q->num));
k=k+1;
}
printf("插入成功\n");
}
voidListinsert_order()//有顺序插入
{
number*q;
number*p=head;
q=(number*)malloc(sizeof(number));
printf("输入您要插入哪个数\n");
scanf("%d",&q->num);
while(p->next)
{
if(p->next->num>=q->num)//插在第一个比数大或等于的的数前
{
q->next=p->next;
p->next->prior=q;
p->next=q;
q->prior=p;
k=k+1;
break;
}
else
{
p=p->next;
}
}
if(p->next==NULL)//插到末尾
{
q->next=NULL;
p->next=q;
q->prior=p;
k=k+1;
}
printf("插入成功\n");
}
voidListdelete()//删除
{
inti;
number*q;
number*p=head;
printf("输入您要删除哪个元素\n");
scanf("%d",&i);
if((i>k)||(i<=0))
{
printf("删除的位置不存在\n");
}
else
{
while(--i)//这里是先减再判断
{
p=p->next;//p指向被删除的元素的前一个元素
}
q=p->next;//q指向被删除的元素
if(q->next==NULL)//删除最后一个元素
{
p->next=NULL;
}
else
{
p->next=q->next;//p的下一个元素指向q的下一个,即跳过被删除元素
q->next->prior=p;//q的下一个元素的前驱指向p,也跳过被删除的元素
}
free(q);//清空删除元素
k=k-1;
}
printf("删除成功\n");
}
六、测试结果
1.最初运行程序时,有如下结果:
2.在输入1后,创建长度为10的斐波那契数列,结果如下:
3.在输入2后,显示数列,结果如下:
4.在输入3后,进行查询操作后,结果如下:
5.在输入4后,进行无序插入操作后,结果如下:
6.在输入5后,进行有序插入操作后,结果如下:
7.在输入6后,进行删除操作后,结果如下:
8.输入其他数字的结果:
七、总结反思
刚做这个题目的时候发现自己结构体和链表学的太浅了,以前学得只是也不能很好的运用。
所以我又复习起了结构体和链表。
一开始用单链表实现,想自己做,但没有头绪,心里有了惧怕,一直没做出来。
看了书本上的几行代码后有了思路,思路也通了。
经过代码的编写和调试,运行出来了,感觉很神奇,而且也找回了信心。
后来要求要用双向链表来实现。
我知道关键的就那几行代码,弄清楚后,也很快调试出来。
在程序的细节上表现的不是很好,代码变量命名随意,代码书写不规范,在翻看了编码规范后,我改进了代码。
时间浪费了,下次要按规定来。
在用户界面上不友善,后来加了些printf语句使程序运行界面更加友善了。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 双向 实验 报告 概要