数据结构课程设计之双向链表操作讲解.docx
《数据结构课程设计之双向链表操作讲解.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计之双向链表操作讲解.docx(15页珍藏版)》请在冰豆网上搜索。
数据结构课程设计之双向链表操作讲解
《数据结构》课程设计实验报告
之双向链表的相关操作
专业:
计算机信息管理
******
学号:
************
******
时间:
2013.1.4
1.问题分析…………………………………………….….1
1.1基本要求…………………………………………………...1
1.2分析过程…………………………………………………...1
2.数据结构描述…………………………………………..1
3.算法设计………………………………………………..2
3.1算法1:
双向链表的建立………………………………...2
3.2算法2:
双向链表的查找……………………………….…2
3.3算法3:
双向链表的插入………………………………...3
3.4算法4:
双向链表的删除………………………………...3
4.程序具体步骤…………………………………..……4
5.程序运行结果………………………………………...10
6.总结……………………………………………….…..10
●1.问题分析
1.1【基本要求】:
建立双向链表,并进行插入,查找,删除等操作。
1.2【分析过程】:
先通过创建函数建立双向链表,由文本文件提供数据。
可以调用查找函数,查找与e值相同的结点是否存在;也可以通过插入函数,在第i个结点前插入值为e的结点,并且调节指针的变化;也可以调用删除函数,删除第i个结点,调节好指针,最后通过保存函数保留数据到文本文件中。
●2.数据结构描述
#include
#include
usingnamespacestd;
typedefstructdulnode{
intdata;
structdulnode*prior;
structdulnode*next;
}dulnode,*dulinklist;
●3.算法设计
3.1算法1:
创建双向链表
statuscreate_dul(dulinklist&l)/*利用尾插法建立头带头结点的双向链表*/
{
l=(dulinklist)malloc(sizeof(dulnode));/*生成头结点*/
l->prior=NULL;
l->next=NULL;/*头结点的指针域初始值为空*/
l->data=-1;
q=l;/*尾指针初始指向头结点*/
FILE*fp;/*定义文件指针的形式*/
if((fp=fopen("F:
\\test1.txt","r+"))==NULL);/*打开文本文件*/
{
printf("cannotopenfile!
\n");
exit(0);
}
intn;
fscanf(fp,"%d",&n);
for(i=0;i{
p=(dulinklist)malloc(sizeof(dulnode));
fscanf(fp,"%d",&p->data);/*在文件读取结点的数据*/
p->next=NULL;/*新结点指针域为空*/
p->prior=q;
q->next=p;/*尾结点指针域指向新结点*/
q=p;/*q指针后移,始终指向尾指针*/
}
fclose(fp);/*关闭文本文件*/
3.2算法2:
双向链表的查找
staduslocateelem_dul(dulinklistl,elemtypee);/*查找双线链表中第一个值为e的结点位置*/
{
p=l->next;/*p指向第一个结点*/
j=1;/*j表示结点位置*/
while((p->data!
=e)&&p){
p=p->next;
++j;
}/*寻找第一个值为e的结点位置*/
if(!
p)return-1;
elsereturn1;
}
3.3算法3:
双向链表的插入
statuslistinsert_dul(dulinklist&l,inti,elemtypee)/*在双向链表l中的第i个位置之前插入新结点s*/
{
p=l;/*p指向头结点*/
j=0;/*j表示结点位置*/
while(p&&(jp=p->next;
++j;
}/*寻找第i-1个结点位置*/
if(!
p||j>i-1)returnERROR;/*在l中确定插入位置,p=NULL或j>i-1时,即插入位置不合法*/
if(!
(s=(dulinklist)malloc(sizeof(dulnode))))returnERROR;/*动态生成新结点失败,则返回错误*/
s->data=e;/*给新结点的数据域赋值*/
s->next=p->next;
p->next->prior=s;
s->prior=p;
p->next=s;/*在双向链表中插入新结点时指针的变化*/
return0;
}
3.4算法4:
双向链表的删除
statuslistdelete_dul(dulinklist&l,inti,elemtype&e);/*在双向链表l中,删除第i个结点*/
{
p=l->next;/*p指向第一个结点*/
intj=1;/*j表示结点位置*/
while(p&&(j
{
p=p->next;
++j;
}/*寻找第i个结点*/
if(!
p||j>i)returnERROR;/*在l中确定第i个元素的位置指针p,p=NULL,即第i个元素不存在*/
e=p->data;/*把指针p的数据域的值赋给e*/
p->prior->next=p->next;
p->next->prior=p->prior;/*在双向链表中删除结点时指针的变化*/
free(p);/*把结点p删掉*/
return0;
}
●4.程序具体步骤
#include"stdio.h"
#include"stdlib.h"
typedefintelemtype;
typedefstructlnode//定义结点类型
{
elemtypedata;
structlnode*next;
structlnode*prior;
}lnode,*linklist;
intinitlist(linklist&L)//初始化单链表
{
L=(linklist)malloc(sizeof(lnode));//表头附加结点
if(!
L)exit(-2);
L->next=L;
L->prior=L;
return1;
}//初始化了一个空表
voidcreatelist(linklist&L)//尾插法生成双向循环链表
{
intx;
linklistq=L;
printf("请输入要插入元素的值(输入0结束):
\n");
scanf("%d",&x);
while(x){
linklistp=(linklist)malloc(sizeof(lnode));
p->data=x;
q->next=p;
L->prior=p;
p->prior=q;
p->next=L;
q=p;
scanf("%d",&x);
}
}
voidshuchulist(linklist&L)//遍历有头结点的双向循环链表
{
linklistp=L->next;
while(p->next!
=L){
printf("%4d",p->data);
p=p->next;
}
printf("%4d",p->data);
printf("\n");
}
intlengthlist(linklistL){//通过链表的遍历来统计长度
linklistp=L->next;
intcount=0;
while(p!
=L){
p=p->next;
count++;
}
returncount;
}
intlistdelete_i(linklist&L,inti){//删除带头结点的双向循环链表中第i个元素
linklistp=L;
intj=0;
if(i>lengthlist(L)){
return0;
}
while(j
p=p->next;++j;
}
p->prior->next=p->next;//删除结点p
free(p);//释放结点p
return1;
}
intlistdelete_x(linklist&L,elemtypex){//删除值为x的元素
linklistp=L->next,q;
inti=0;
while(p!
=L){
if(p->data==x){
q=p->next;
p->next->prior=p->prior;
p->prior->next=p->next;
free(p);
p=q;
++i;
}
else
p=p->next;
}
returni;
}
voidpaixu(linklistL){//将链表排成非递减链表
intt;
linklistp;
for(inti=1;ip=L->next;
for(intj=0;jif(p->data>p->next->data){
t=p->data;
p->data=p->next->data;
p->next->data=t;
}
p=p->next;
}
}
}
voidlinklistinsert(linklist&L,elemtypee){//在非递减有序双向循环链表中实现插入元素e仍有序
linklistp=L->next;
linklistq=(linklist)malloc(sizeof(lnode));
q->data=e;
if(L->prior->dataL->prior->next=q;
q->prior=L->prior;
q->next=L;
L->prior=q;
}else{
while(p->datap=p->next;
}
//把e插到第一个大于或等于它的元素之前
p->prior->next=q;
q->prior=p->prior;
q->next=p;
p->prior=q;
}
}
intpanduan(linklistL){//判断双向循环链表中元素是否对称
linklistp=L->next,q=L->prior;
if(lengthlist(L)%2){
while(p->data==q->data&&p!
=q){
p=p->next;q=q->prior;
}
if(q==p)
return1;
else
return0;
}else{
while(p->data==q->data&&p->next!
=q){
p=p->next;q=q->prior;
}
if(p->data==q->data)
return1;
else
return0;
}
}
voidjioushu(linklistL){//把链表中奇数放到偶数之前
linklistp=L->next,q,s;
s=L->prior;
while(p!
=s){
if(p->data%2)
p=p->next;
else{
q=p->next;
p->prior->next=p->next;p->next->prior=p->prior;//把p从链表中取出
p->prior=L->prior;
L->prior->next=p;
p->next=L;
L->prior=p;
p=q;
}
}
}
voidmain()
{
linklistLa;
intmenu,flag,i,x,c;
do{
printf("制作人:
陶鹏鹏\n");
printf("学号:
201140130241\n");
printf("专业:
计算机信息管理\n");
printf("指导老师:
吴志强\n");
printf("\n");printf("\n");
printf("1.利用尾插法建立双向循环链表链表\n");
printf("2.遍历双向循环链表\n");
printf("3.双向循环链表中删除一个指定元素\n");
printf("4.在非递减有序双向循环链表中实现插入元素e仍有序\n");
printf("5.判断双向循环链表中元素是否对称若对称返回1否则返回0\n");
printf("6.设元素为正整型,实现算法把所有奇数排列在偶数之前\n");
printf("0.退出\n");
printf("\n请输入所选菜单(0-6):
");
scanf("%d",&menu);
switch(menu){
case1:
initlist(La);createlist(La);break;
case2:
printf("链表中的元素为:
\n");shuchulist(La);break;
case3:
printf("请选择删除方式:
1删除值为x的结点2删除第i个结点");
scanf("%d",&c);
if(c==1){
printf("请输入要删除元素的值:
");
scanf("%d",&x);
flag=listdelete_x(La,x);
if(flag){
printf("删除成功!
\n");
printf("删除后的链表为:
\n");
shuchulist(La);
}else
printf("删除失败!
\n");
}elseif(c==2){
printf("请输入要删除的位置:
");
scanf("%d",&i);
flag=listdelete_i(La,i);
if(flag){
printf("删除成功!
\n");
printf("删除后的链表为:
\n");
shuchulist(La);
}else
printf("删除失败!
\n");
}
break;
case4:
printf("把原始链表初始化为非递减有序列表为:
\n");
paixu(La);
shuchulist(La);
printf("请输入要插入的元素的值:
");
scanf("%d",&x);
linklistinsert(La,x);
printf("插入后的链表为:
\n");
shuchulist(La);
break;
case5:
flag=panduan(La);
if(flag)
printf("链表对称!
\n");
else
printf("链表不对称!
\n");
break;
case6:
printf("排列之前为:
\n");
shuchulist(La);
jioushu(La);
printf("排列之后为:
\n");
shuchulist(La);break;
case0:
exit(0);
}
}while(menu);
}
●5.程序运行结果
●6.总结:
通过此次数据结构的课程设计,我对程序的编程,编译,执行等有了更深的认识。
理解到思路对于一个程序的重要性,在整个设计过程中,遇到了很多不同的问题,但通过尝试,努力和老师的帮助最终都解决了,感到很有成就感。
从中,我意识到程序的成功不仅仅是消除语法上的错误,而且还要执行成功。
缺乏完整的思路,尽管语法正确,程序还是无法执行。
数据结构的设计考验的不仅仅是我们对书本知识的理解,还考验了我们分析事物时思维的逻辑紧密性,加深并巩固了我对数据结构的认识。
总的来说,这次的数据结构课程设计加深了我对数据结构的认识,也学到了相关的知识,并且巩固了课堂上所学的知识,还锻炼了实践的应用操作能力,感受颇深,也收获了成功的喜悦。