课程实验报告课程名称:数据结构专业班级:信安学号:姓名:指导教师:报告日期:2015.4.5计算机科学与技术学院目录1 课程实验概述 (1)2 实验一基于顺序结构的线性表实现2.1 问题描述 (2)2.2 系统设计 (2)2.3 系统实现 (7)2.4 效率分析 (11)3 实验二基于链式结构的线性表实现3.1 问题描述 (12)3.2 系统设计 (12)3.3 系统实现 (14)3.4 效率分析 (22)4 实验三基于二叉链表的二叉树实现4.1 问题描述 (23)4.2 系统设计 (23)4.3 系统实现 (32)4.4 效率分析 (43)5 实验总结与评价 (45)1 课程实验概述上机实验是对学生的一种全面综合训练,是与课堂听课、自学和练习相辅相成的必不可少的一个教学环节。
实验目的着眼于原理与应用的结合,使学生学会如何把书上的知识用语解决实际问题,能够理解和运用常用的数据结构,如线性表、栈、队列、树、图、查找表等,并在此基础上建立相应的算法;通过上机实验使学生了解算法和程序的区别,培养学生把算法转换为程序的能力,提高学生解决实际问题的能力;学会分析研究计算机加工的数据结构的特性,以便为应用涉及的数据选择适当的逻辑结构、存储结构及其相应的算法,并初步掌握算法的时间分析和空间分析的技术。
2 实验一基于顺序结构的线性表实现2.1 问题描述编写一个程序,实现顺序表的各种基本运算,并在此基础上完成以下功能:1) 初始化顺序表;2) 释放顺序表;3) 判断顺序表L是否为空;4) 输出顺序表L的长度;5) 输出顺序表L的第i个元素;6) 输出元素e的位置;7) 输出元素e的前一个元素;8) 输出元素e的后一个元素;9) 在第i个元素位置上插入f元素;10) 删除L的第i个元素;11) 输出顺序表L;12) 保存顺序表L的数据。
2.2 系统设计1、数据类型顺序表:typedef struct{ElemType * elem; //线性表首地址int length; //线性表当前长度int listsize; //线性表最大长度}SqList;数据类型:int(可以在头文件中更改数据类型)输入形式:文件读取、键盘输入输入范围:-2^15~2^162、函数返回状态判断为真:TRUE 0判断为假:FALSE -1函数正确执行:OK -2函数执行错误:ERROR -3元素不存在:NOTEXIST -4内存分配溢出:OVERFLOW -53、函数设计InitList(&L)操作前提:L是一个未初始化的线性表。
操作结果:将L初始化为一个空的线性表。
DestroyList(&L)操作前提:线性表L已存在。
操作结果:销毁线性表L。
ListEmpty(L)操作前提:线性表L已存在。
操作结果:若L为空表,则返回TURE,否则返回FALSE。
ListLength(L)操作前提:线性表L已存在。
操作结果:返回L中数据元素个数。
GetElem(L, i,&e)操作前提:线性表L已存在,1≤i≤ListLength(L)。
操作结果:用e返回L中第i个元素的值。
LocateElem (L,e)操作前提:线性表L已存在。
操作结果:返回L中第一个e的位序。
若这样的数据元素不存在,则返回值为0。
PriorElem (L,e,&proi)操作前提:线性表L已存在。
操作结果:返回L中第一个e的前一个数据元素。
若这样的数据元素不存在,则返回值为0。
NextElem (L,e,&next)操作前提:线性表L已存在。
操作结果:返回L中第一个e的后一个的数据元素。
若这样的数据元素不存在,则返回值为0。
ListInsert (&L,i ,e)操作前提:线性表L已存在,1≤i≤ListLength(L)+1。
操作结果:在L中第i个位置之前插入新的数据元素e,L的长度+1。
ListDelete (&L,i, e)操作前提:线性表L已存在且非空,1≤i≤ListLength(L)。
操作结果:删除L的第i个元素数据,并用e返回其值,L的长度—1。
DisplayList(L)操作前提:线性表L已存在。
操作结果:打印表中元素。
SaveList(L)操作前提:线性表L已存在。
操作结果:保存表中元素。
4、主要函数流程图ProiElem:这里的查找元素操作可直接调用LocateElem函数返回元素的位置,NextElem 函数的流程图与此相似,这里不在赘述)这个函数最主要的部分就是检查参数与元素的移位操作,若参数不合法(传入空线性表、插入位置在线性表之外)极易出现访问数组外元素问题;元素移位操作要在不丢失数据的前提下(从最后一个元素开始)进行。
删除函数同样最主要的部分就是检查参数与元素的移位操作,若参数不合法(传入空线性表、删除位置在线性表之外)极易出现访问数组外元素问题;元素移位操作要在不丢失数据的前提下(从被删除的元素开始)进行。
2.3 系统实现这里也只给出主要函数的代码,完整代码会在附录给出函数名:LocateElem参数:线性表L、要查找的元素返回值:若元素存在,返回位置,否则返回错误信息函数功能:获取元素的位置status LocateElem(SqList L,ElemType e){if( !L.elem )return ERROR;for( int i=1; i<L.length+1; i++ ){if( e == L.elem[i] )return i;}return NOTEXIST;}函数名:PriorElem参数:线性表L、查找的元素、带回元素值的形参返回值:函数执行情况成功为OK,否则ERROR函数功能:获取元素的前继节点元素status PriorElem(SqList L,ElemType cur,ElemType & pre_e) {/*不可获取线性表长度之外的元素,第0号元素不用*/ if( !L.elem )return ERROR;int pos;pos = LocateElem( L, cur );if( pos<1 )return ERROR;if( pos == 1 )return NOTEXIST;pre_e = L.elem[pos-1];return OK;}函数名:ListInsert参数:线性表L(引用)、要插入的位置及元素返回值:是否插入成功函数功能:插入元素到指定位置status ListInsert(SqList & L,int i,ElemType e){/*不可获取线性表长度之外的元素,第0号元素不用*/ if( !L.elem || i>L.length+1 || i<1 )return ERROR;if( L.length == L.listsize )return OVERFLOW;for( int j=L.length+1; j>i; j-- ){L.elem[j] = L.elem[j-1];}L.elem[i] = e;L.length++;return OK;}函数名:ListDelete参数:线性表L(引用)、位置、带回被删除的元素e返回值:是否删除元素成功函数功能:删除指定位置的元素并带回元素status ListDelete(SqList & L,int i,ElemType & e){/*不可获取线性表长度之外的元素,第0号元素不用*/ if( !L.elem || i>L.length || i<1 )return ERROR;e = L.elem[i];for( int j=i; j<L.length; j++ ){L.elem[j] = L.elem[j+1];}L.length--;return OK;}调试分析(1)调试过程中主要遇到哪些问题?是如何解决的?调式过程中发现总是粗心大意忘了加分号或者打错字,所以学习C语言一定要细心仔细,不能着急。
用DisplayList函数时出现了问题,后来经过询问同学和查阅书本对程序进行了改正,使其能够正确进行。
(2)经验和体会通过这次上机实验,对顺序表的各功能有了进一步的了解和学习,也对C语知识进行了巩固。
实验结果截图实验测试数据为:1、2、3、4、5、6、7、8、9。
这里依然只给出主要函数结果。
1)查找元素位置:2)查找前继元素:3)插入元素:4)删除元素:5)遍历线性表:2.4 效率分析由于线性表具有随机访问的特性,所以线性表操作的时间基本来自于线性表的遍历、插入及删除操作。
假定线性表中有n个元素。
1)获取元素位置:最好的情况:第一个元素即为所要查找的元素,执行1次操作;最坏的情况:最后一个元素为要查找的元素,执行n次操作;若所有元素访问的概率相等,则要执行(n+1)/2次操作。
总体来说时间复杂度为O(n)。
2)插入元素:最好的情况:插入到线性表尾,执行1次操作;最坏的情况:插入到线性表头,执行n次操作;若所有元素访问的概率相等,则要执行(n+1)/2次操作。
总体来说时间复杂度为O(n)。
3)删除元素:最好的情况:删除线性表尾元素,执行1次操作;最坏的情况:删除线性表头元素,执行n次操作;若所有元素访问的概率相等,则要执行(n+1)/2次操作。
总体来说时间复杂度为O(n)。
结果分析:线性表比较适合经常访问但修改较少的实际运用。
3 实验二基于链式结构的线性表实现3.1 问题描述编写一个程序,实现线性链表的各种基本运算,并在此基础上完成以下功能:1) 初始化线性链表;2) 释放线性链表;3) 判断线性链表L是否为空;5) 输出线性链表L的长度;5) 输出线性链表L的第i个元素;6) 输出元素e的位置;7) 输出元素e的前一个元素;8) 输出元素e的后一个元素;9) 在第i个元素位置上插入f元素;10) 删除L的第i个元素;11) 输出线性链表L;12) 保存线性链表L的数据。
3.2 系统设计1、数据类型线性链表:struct LinkList{ElemType data; //链表元素LinkList *next; //指向后继节点的指针}数据类型:int(可以在头文件中更改数据类型)输入形式:文件读取、键盘输入输入范围:-2^15~2^162、函数返回状态判断为真:TRUE 0判断为假:FALSE -1函数正确执行:OK -2函数执行错误:ERROR -3元素不存在:NOTEXIST -4内存分配溢出:OVERFLOW -53、函数设计InitList(&L)操作前提:L是一个未初始化的线性表。
操作结果:将L初始化为一个空的线性表。
DestroyList(&L)操作前提:线性表L已存在。