链表实验报告.docx
- 文档编号:30464424
- 上传时间:2023-08-15
- 格式:DOCX
- 页数:16
- 大小:104.92KB
链表实验报告.docx
《链表实验报告.docx》由会员分享,可在线阅读,更多相关《链表实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
链表实验报告
重庆工商大学
《数据结构》课程实验报告封面
专业班级:
______学号:
_______
学生姓名:
_____________实验室:
__________________
实验题目:
_______双链表的基本操作方法_______________
指导教师:
____________成绩:
__________________
日期:
2013年_9月____日第_4_周星期__3_节次____
评分表
实验报告质量
序号
项目
总分
自评分
互评分
组长评分
教师评分
1
算法思想
2
2
算法描述
3
3
实验数据与结果
10
4
总结
4
5
排版
2
源程序质量
6
正确性
63
7
友好性
4
8
可读性
4
9
健壮性
4
10
创新与多样性
4
合计
总分
评分人签字
目录
实验题目----------------------------------------------------------------------------------1
实验目的----------------------------------------------------------------------------------1
实验内容----------------------------------------------------------------------------------1
实验要点与要求-------------------------------------------------------------------------1
算法思想----------------------------------------------------------------------------------1
算法描述----------------------------------------------------------------------------------1
算法流程图----------------------------------------------------------------------------------4
实验测试与结果-------------------------------------------------------------------------5
总结体会----------------------------------------------------------------------------------5
源代码----------------------------------------------------------------------------------6
实验报告的内容与要求
1、实验题目
双链表的基本操作
2、实验目的
了解双链表的结构特点及有关概念,掌握双链表的基本操作算法。
3、实验内容
实现双链表的初始化、销毁、建立、插入、删除和查找等基本操作。
4、实验要点与要求
1.处理的数据类型即ElemType的类型:
基本版要求:
整型、字符型
扩展版要求:
字符串型(基础较好的同学)
2.参数类型分别用指针、引用和引用型指针
5、算法思想
和顺序表不同的是,链表不需要占用一整块事先分配的固定的内存空间,而是采用动态空间链接的方式进行。
在每个存储节点都包含了元素本身的信息(数据域)和元素之间的逻辑联系(指针域),就双链表而言,其指针域包含了前驱指针和后续指针,分别用于指向当前节点的上一个节点和下一个节点,故而,对双链表进行操作的时候,要考虑其前驱指针和后续指针的指向,否则容易引起混乱。
在链表的操作中,首先最重要的是定义一个头结点,因为指向头结点的指针唯一标识该链表,本次程序采用了不包含任何数据的头节点定义方式。
6、算法描述及流程图
由于程序的分支较多,需要实现的功能也不尽相同,和顺序表一样,我选择了其中插入数据的分支来具体描述其算法,并比较链表和顺序表的操作上的不同:
do{
c=ListLength(L);
cout<<"\n请输入您需要插入的节点位置(0 "; cin>>number; cout<<"插入的数据: "; if(number<0||number>l+1){cout<<"输入错误! "< cin>>date; ListInsert(L,number,date); cout<<"\n是否需要继续插入? \n"; cout<<"1.是0.否"< cout<<"请选择: "; cin>>ctrl; }while(ctrl==1);break; boolListInsert(DLinkList*&L,inti,ElemTypee)//插入数据 { intj=0; DLinkList*p=L,*s; while(j =NULL) { j++; p=p->next; } if(p==NULL) returnfalse; else{ s=(DLinkList*)malloc(sizeof(DLinkList)); s->date=e; s->next=p->next; if(p->next! =NULL) p->next->prior=s; p->next=s; s->prior=p; cout<<"插入成功! "< returntrue; } } 首先,和顺序表一样的是,整个输入分支采用do-while循环进行控制,以便于我们可以多次输入;分支开始的时候,需要用输入插入的元素的位置,并通过一个if条件句判断用户输入的节点位置是否合法,如果节点位置不合法,则提示错误并提前结束分支,返回主菜单。 节点位置合法则提示用户输入需要插入的数据,完成后调用ListInsert函数对链表进行插入,和顺序表不一样的是插入的具体实现方式: 在插入之前,分配一个指向空节点的指针s和指向头结点的指针p,用p指针找到插入位置的上一个节点位置,如果找到开始执行插入操作,否则退出。 插入开始,把用户输入的数据存储在节点s中,把p节点的后继指针指向的节点赋值给s的后继指针,如果p的next域不是空节点,修改其前驱指针指向s;把p的后继指针指向s,s的前驱指针指向p,则s指向的数据就成功插入到链表之中了。 基本流程图如下: 7、实验数据及实验结果 由于程序和顺序表一样定义为char类型,故而测试的数据和顺序表一样: 输入整型,浮点型,字符型,字符串这几种不同类型的数据后,程序的不同输出结果,并且根据顺序表节点数为正整数的特征,测试了输入浮点数,字符,字符串,负数这几种情况下的输出结果。 对于插入的数据来说总共测试了以下几种数据测试数据及结果如下: 序号 测试类型 输入数据 期望输出结果 实际输出结果 测试结论 合法数据 1,2,3,4,a,b,c,d 1,2,3,4,a,b,c,d 1,2,3,4,a,b,c,d 程序对于定义范围内的值可以正确处理 非法数据 -1 1.5 go -1 1.5 go - 死循环,死循环 超出定义范围的值会引起程序崩溃或者错误 对于节点,主要测试了以下几种特殊状态的值 实验数据及结果如下: 测试类型 输入节点 期望输出结果 实际输出结果 测试结论 非法节点 -1 1.5 相应节点的数据 输入错误! 程序执行正确,但存入链表的字符为’.’ 对负数可以正确处理 浮点型数据转化为3个字符处理 非法节点 A asd 相应节点的数据 死循环 死循环 错误的数据类型引起程序错误 通过对于程序处理异常数据的结果进行分析,我发现和双链表的错误和顺序表一样,都是数据类型的不兼容引起程序崩溃 8、实验总结与体会 程序实现了双链表的基本操作,和顺序表相比较,链表的操作更灵活,没有固定的长度限制,只要内存足够,就可以链接数据。 大大提高了程序的灵活性和数据处理能力,但是我也发现,链表的指针指向很容易出错,如果指向不对,就会引起系统混乱出现数据异常或者是编译不通过的情况,这样一来对于逻辑要求又有了更高的要求。 9、源代码 #include #include usingnamespacestd; typedefcharElemType; typedefstructDNode { ElemTypedate;//数据域 structDNode*prior;//前驱指针 structDNode*next;//后继指针 }DLinkList; //函数声明 externvoidInitList(DLinkList*&L);//初始化双链表 externvoidDestroyList(DLinkList*&L);//销毁双链表 externintListLength(DLinkList*L);//链表求长 externvoidDispList(DLinkList*L);//输出链表 externboolGetElem(DLinkList*L,inti,ElemType&e);//按位置查找 externintLocateElem(DLinkList*L,ElemTypee);//按元素查找 externboolListInsert(DLinkList*&L,inti,ElemTypee);//插入数据 externboolListDelete(DLinkList*L,inti,ElemType&e);//删除第i个位置的元素 //函数定义 voidInitList(DLinkList*&L)//初始化链表 { L=(DLinkList*)malloc(sizeof(DLinkList)); L->next=L->prior=NULL; cout<<"新建成功! "< } intListLength(DLinkList*L)//链表求长 { inti=0; DLinkList*p=L->next; while(p! =NULL) { p=p->next; i++; } returni; } voidDispList(DLinkList*L)//输出链表 { DLinkList*p=L->next; intc; c=ListLength(L); if(c==0)cout<<"链表为空,请插入数据! \n"< else{ while(p! =NULL) { cout< p=p->next; } cout< } } boolGetElem(DLinkList*L,inti,ElemType&e)//按位置查找 { intj=0; DLinkList*p=L; while(j =NULL) { j++; p=p->next; } if(p==NULL) returnfalse; else { e=p->date; returntrue; } } intLocateElem(DLinkList*L,ElemTypee)//按元素师查找 { inti=1; DLinkList*p=L->next; while(p! =NULL&&p->date! =e) { p=p->next; i++; } if(p==NULL) return0; elsereturni; } boolListInsert(DLinkList*&L,inti,ElemTypee)//插入数据 { intj=0; DLinkList*p=L,*s; while(j =NULL) { j++; p=p->next; } if(p==NULL) returnfalse; else{ s=(DLinkList*)malloc(sizeof(DLinkList)); s->date=e; s->next=p->next; if(p->next! =NULL) p->next->prior=s; p->next=s; s->prior=p; cout<<"插入成功! "< returntrue; } } boolListDelete(DLinkList*L,inti,ElemType&e)//删除第i个元素 { intj=0; DLinkList*p=L,*s; while(j =NULL) { j++; p=p->next; } if(p==NULL) returnfalse; else { s=p->next; if(s==NULL) returnfalse; p->next=s->next; if(s->next! =NULL) p->next->prior=p; free(s); cout<<"删除成功! "< returntrue; } } //测试函数 intmain() { DLinkList*L; intchoose;//主菜单选择分支 intnumber;//存储数据位置 ElemTypedate;//储存数据 intc;//顺序表长度 intctrl;//函数继续控制变量 for(;;) { cout<<""< cout<<"*-*-*-**-*-*-**-*-*-*"< cout<<"*欢迎使用双向链表*"< cout<<"*1.新建链表*"< cout<<"*2.数据插入*"< cout<<"*3.位置查找*"< cout<<"*4.元素查找*"< cout<<"*5.删除数据*"< cout<<"*6.遍历链表*"< cout<<"*7.退出程序*"< cout<<"*-*-*-**-*-*-**-*-*-*"< cout<<"请选择: "; cin>>choose; switch(choose){ case1: InitList(L);break; case2: do{ c=ListLength(L); cout<<"\n请输入您需要插入的节点位置(0 "; cin>>number; if(number<0||number>c+1){cout<<"输入错误! "< cout<<"插入的数据: "; cin>>date; ListInsert(L,number,date); cout<<"\n是否需要继续插入? \n"; cout<<"1.是0.否"< cout<<"请选择: "; cin>>ctrl; }while(ctrl==1);break; case3: do{ for(;;){ cout<<"\n请输入您需要查询的节点: "; cin>>number; if(number<=0){cout<<"\n节点不合法! \n";} elsebreak; } date=GetElem(L,number,date); if(GetElem(L,number,date)&&date! =NULL) cout<<"该节点所在数据是: "< elsecout<<"\n无此节点或节点无数据! \n"< cout<<"\n是否需要继续查询? \n1.是0.否"< cout<<"请选择: "; cin>>ctrl; }while(ctrl==1);break; case4: do{ cout<<"\n请输入您需要查询的数据值: "; cin>>date; number=LocateElem(L,date); if(LocateElem(L,date)&&number>0) cout<<"该数据所在节点为: "< elsecout<<"\n不存在该数据! \n"< cout<<"\n是否需要继续查询? \n1.是0.否"< cout<<"请选择: "; cin>>ctrl; }while(ctrl==1);break; case5: do{ cout<<"\n请选择您需要删除的节点: "; cin>>number; ListDelete(L,number,date); cout<<"\n是否继续删除? "< cout<<"1.是0.否\n请选择: "< cin>>ctrl; }while(ctrl==1);break; case6: cout<<"\n双向链表所有数据: ";DispList(L);cout< case7: cout<<"感谢您的使用,再见! \n\n"< }//switch尾 }//for尾 }//main尾
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告