线性表的实现与操作(二)
实验一 线性表的基本操作实现及其应用

实验一线性表的基本操作实现及其应用一、实验目的1、熟练掌握线性表的基本操作在两种存储结构上的实现。
2、会用线性链表解决简单的实际问题。
二、实验内容题目一、该程序的功能是实现单链表的定义和操作。
该程序包括单链表结构类型以及对单链表操作的具体的函数定义和主函数。
其中,程序中的单链表(带头结点)结点为结构类型,结点值为整型。
单链表操作的选择以菜单形式出现,如下所示:please input the operation:1.初始化2.清空3.求链表长度4.检查链表是否为空5.检查链表是否为满6.遍历链表(设为输出元素)7.从链表中查找元素8.从链表中查找与给定元素值相同的元素在表中的位置9.向链表中插入元素 10. 从链表中删除元素其他键退出。
其中黑体部分必做题目二、约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,每个人持有一个正整数密码。
开始时任选一个正整数做为报数上限m,从第一个人开始顺时针方向自1起顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数。
如此下去,直到所有人全部出列为止。
令n最大值取30。
要求设计一个程序模拟此过程,求出出列编号序列。
struct node(一)1.进入选择界面后,先选择7,进行插入:2.选择4,进行遍历,结果为:3.选择2,得出当前链表长度.4.选择3,得出当前链表为.5.选择分别选择5、6进行测试.6.选择8,分别按位置和元素值删除.7.选择9,或非1-8的字符,程序结束.(二) 实验总结通过这次实验,我对线性链表有了更深的理解,深入明白了线性存储结构与链式存储结构在内存存储的不同特点,同时我还学会了用这些知识实际解决一些问题,能够更加熟练地将算法转化为实际程序。
同时,在写程序和调试程序的过程中,学会了一些书写技巧和调试技巧,这对于自己能在短时间高效的写出正确地程序有很大作用。
四、主要算法流程图及程序清单 1. 主要算法流程图:(1) 从单链表表中查找与给定元素值相同的元素在链表中的位置p=p->nextp&&!(p->data==xtrue调用函数,传入参数L ,xp=L->next2.程序清单:#include<iostream> using namespace std; #include<>#include<>/* 预处理命令 */#define OK 1;#define ERROR 0;#define OVERFLOW -1;/* 单链表的结点类型 */typedef struct LNode{int data;struct LNode *next;}LNode,*LinkedList;/*初始化单链表*/LinkedList LinkedListInit(){空"<<endl;cout<<"\t\t\t"<<"2.求链表长度"<<endl;cout<<"\t\t\t"<<"3.检查链表是否为空"<<endl;cout<<"\t\t\t"<<"4.遍历链表"<<endl;cout<<"\t\t\t"<<"5.从链表中查找元素 "<<endl;cout<<"\t\t\t"<<"6.从链表中查找与给定元素值相同的元素在表中的位置"<<endl;cout<<"\t\t\t"<<"7.向链表中插入元素"<<endl;cout<<"\t\t\t"<<"8.从链表中删除元素"<<endl;cout<<"\t\t\t"<<"9.退出"<<endl;}/*主函数*/int main(){链表长度case 2:{cout<<"\t\t\t链表长度为:"<<LinkedListLength(L)<<endl;getch();}break;查链表是否为空case 3:{if (!LinkedListEmpty(L)){cout<<"\t\t\t链表不为空!"<<endl;}else{cout<<"\t\t\t链表为空!"<<endl;}getch();}break;历链表case 4:{LinkedListTraverse(L);getch();}break;链表中查找元素case 5:{cout<<"\t\t\t请输入要查询的位置i:";int j;cin>>j;if (LinkedListGet(L,j)){cout<<"\t\t\t位置i的元素值为:"<<LinkedListGet(L,j)->data<<endl;}else{cout<<"\t\t\ti大于链表长度!"<<endl;}getch();}break;链表中查找与给定元素值相同的元素在表中的位置case 6:{cout<<"\t\t\t请输入要查找的元素值:";int b;cin>>b;if (LinkedListGet1(L,b)){cout<<"\t\t\t要查找的元素值位置为:"<<LinkedListGet1(L,b)<<endl;cout<<"\t\t\t要查找的元素值内存地址为:"<<LinkedListLocate(L,b)<<endl;}else{cout<<"\t\t\t该值不存在!"<<endl;}getch();}break;链表中插入元素case 7:{cout<<"\t\t\t请输入要插入的值:";int x; cin>>x;cout<<"\t\t\t请输入要插入的位置:";int k; cin>>k;if(LinkedListInsert(L,k,x)){cout<<"\t\t\t插入成功!"<<endl;}else{cout<<"\t\t\t插入失败!"<<endl;}getch();}break;链表中删除元素case 8:{cout<<"\t\t\t1.按位置删除"<<endl;cout<<"\t\t\t2.按元素删除"<<endl;int d;cout<<"\t\t请选择:";cin>>d;switch(d){case 1:{cout<<"\t\t\t请输入删除位置:";cin>>d;int y;if (LinkedListDel(L,d,y)){cout<<"\t\t\t"<<y<<"被删除!"<<endl;}else{cout<<"\t\t\t删除失败!"<<endl;}}break;case 2:{cout<<"\t\t\t请输入删除元素:";int y;cin>>y;if (LinkedListDel(L,y)){cout<<"\t\t\t"<<y<<"被删除!"<<endl;}else{cout<<"\t\t\t删除失败!"<<endl;}}}getch();}break;}}return 1;}题二约瑟夫环问题算法、思想为了解决这一问题,可以先定义一个长度为30(人数)的数组作为线性存储结构,并把该数组看成是一个首尾相接的环形结构,那么每次报m的人,就要在该数组的相应位置做一个删除标记,该单元以后就不再作为计数单元。
线性表的类型定义、顺序表示和实现

i=n 只删 an即可 1≤i≤n -1 将ai+1 ~an前移
23
bool deleteElem(SqList& L,int pos)
typedef int ElemType;
typedef char ElemType;
等;
②同一线性表中的数据元素必须具有相同的特性,属同一类 型;
③a2,关…系, ra是i-1,一a个i, a有i+1序, …偶,对an的)集,合a,i-1即领对先于于非ai,空表的示线了性数表据(元a1,素 之间的相邻关系,称ai-1是ai的直接前驱,ai是ai-1的直接后继 ;
6
2.1.3 操作举例
例:假设利用两个线性表La和Lb分别表示两 个集合A和B,求一个新的集合A=A∪B。
算法:
– ①取得Lb中的1个元素; – ②在La中查找这个元素; – ③若不存在:插入La中;若存在,取Lb中下一个
元素,重复 ①、②、③,直到取完Lb的每个元素 。
7
void unionList(SqList &la,SqList lb)
10
线性表的顺序存储结构示意图
存储地址
loc(a1) loc(a1)+ k
内存空间状态 逻辑地址
a1
1
a2
2
…
…
…
loc(a1)+ (i- 1)k
ai
i
…
…
…
loc(a1)+ (n- 1)k
an
n 空闲
顺序存储结构可以借助于高级程序设计语言中的一维数组来表示。
11
用C++语言描述的顺序表类型如下所示: sqlist.h
数据结构习题及答案与实验指导(线性表)2

第2章线性表线性表是一种最基本、最常用的数据结构,它有两种存储结构——顺序表和链表。
本章主要介绍线性表的定义、表示和基本运算的实现。
重点讨论了线性表的存储结构,以及在顺序、链式两种存储结构上基本运算的实现。
重点提示:●线性表的逻辑结构特征●线性表的顺序存储和链式存储两种存储结构的特点●在两种存储结构下基本操作的实现2-1 重点难点指导2-1-1 相关术语1.线性表线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,通常记为:(a1,a2,…,a n),其中n为表长,n=0时称为空表。
要点:一种逻辑结构,其数据元素属于相同数据类型,之间的关系是线性关系。
2.顺序表顺序存储的线性表。
要点:按线性表中的元素的逻辑顺序依次存放在地址连续的存储单元里,其存储特点:用物理上的相邻实现逻辑上的相邻。
3.链表用链表存储的线性表。
要点:链表是通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,对每个结点的地址是否连续没有要求。
4.单链表每个结点除了数据域外还有一个指向其后继的指针域。
要点:通常将每个元素的值和其直接后继的地址作为一个结点,通过每个结点中指向后继结点的指针表示线性表的逻辑结构。
5.头指针要点:头指针是一个指针变量,里面存放的是链表中首结点的地址,并以此来标识一个链表。
如链表H,链表L等,表示链表中第一个结点的地址存放在指针变量H、L中。
通常用头指针来惟一标识一个链表。
6.头结点要点:附加在第一个元素结点之前的一个结点,头指针指向头结点。
当该链表表示一个非空的线性表时,头结点的指针域指向第一个元素结点;为空表时,该指针域为空。
7.头结点的作用要点:其作用有两个,一是使对空表和非空表的处理得到统一;二是在链表的第一个位置上的操作和在其他位置上的操作一致,无需特殊处理。
2-1-2 线性表的顺序存储1.顺序表顺序存储的线性表称为顺序表。
其特点是:用一组地址连续的存储单元来依次存放线性表的数据元素,因此数据元素的逻辑顺序和物理次序一致(这是顺序存储的核心所在)。
数据结构 线性表

第1讲线性表本章主要掌握如下内容:线性表的定义和基本操作,线性表的实现,线性表的顺序存储结构及链式存储结构,线性表的应用。
知识点分析(一)线性表的定义和基本操作1.线性表基本概念1)定义:是由相同类型的结点组成的有限序列。
如:由n个结点组成的线性表(a1, a2, …, a n)a1是最前结点,a n是最后结点。
结点也称为数据元素或者记录。
2)线性表的长度:线性表中结点的个数称为其长度。
长度为0的线性表称为空表。
3)结点之间的关系:设线性表记为(a1,a2,…a i-1 , a i, a i+1 ,…a n),称a i-1是a i的直接前驱结点....(简称前驱),a i+1是a i的直接后继结点....(简称后继)。
4)线性表的性质:①线性表结点间的相对位置是固定..的,结点间的关系由结点在表中的位置确定。
②如果两个线性表有相同的数据结点,但它们的结点顺序不一致,该两个线性表也是不相等的。
注意:线性表中结点的类型可以是任何数据(包括简单类型和复杂类型),即结点可以有多个成分,其中能唯一标识表元的成分称为关键字(key),或简称键。
以后的讨论都只考虑键,而忽略其它成分,这样有利于把握主要问题,便于理解。
『经典例题解析』线性表的特点是每个元素都有一个前驱和一个后继。
( )【答案】错误。
【解析】线性表的第一个数据元素没有前驱,最后一个元素没有后继。
其余的所有元素都有一个前驱和后继。
2.线性表的抽象数据类型线性表是一个相当灵活的数据结构,其长度可以根据需要增加或减少。
从操作上讲,用户不仅可以对线性表的数据元素进行访问操作,还可以进行插入、删除、定位等操作。
1)线性表的基本操作假设线性表L有数据对象 D={ai | ai∈ElemSet,i=1,2,3,…,n,n>=0},数据元素之间的关系R={<ai-1,ai>|ai-1,ai∈D,i=1,2,…,n},则线性表L的基本操作如下所示:●InitList(&L):其作用是构造一个长度为0的线性表(空线性表);●DestoryList(&L):其作用是销毁当前的线性表L;●ClearList(&L):清空线性表L,使之成为空表;●ListLength(L):返回线性表L的长度,即线性表中数据元素的个数;●ListEmpty(L) :判断线性表L是否为空表,是则返回True,否则返回False;●GetElem(L,i,&e):将线性表L中第i个数据元素的值返回到变量e中;●LocateELem(L,e,compare( )) :判断线性表L中是否存在与e满足compare()条件的数据元素,有则返回第一个数据元素;●PriorElem(L,cur_e,&pri_e):返回线性表L中数据元素cur_e的前驱结点;●NextElem(L,cur_e,&next_e):返回线性表L中数据元素cur_e的后继结点;●ListInsert(&L,i,e):向线性表L的第i个位置之前插入一个数据元素,其值为e;●ListDelete(&L,i,&e):删除线性表L的第i个数据元素,并将该数据元素的值返回到e中;●ListTraverse(L,visit()):遍历线性表中的每个数据元素。
数据结构与算法分析实验报告

数据结构与算法分析实验报告一、实验目的本次实验旨在通过实际操作和分析,深入理解数据结构和算法的基本概念、原理和应用,提高解决实际问题的能力,培养逻辑思维和编程技巧。
二、实验环境本次实验使用的编程语言为 Python,使用的开发工具为 PyCharm。
操作系统为 Windows 10。
三、实验内容(一)线性表的实现与操作1、顺序表的实现使用数组实现顺序表,包括插入、删除、查找等基本操作。
通过实验,理解了顺序表在内存中的存储方式以及其操作的时间复杂度。
2、链表的实现实现了单向链表和双向链表,对链表的节点插入、删除和遍历进行了实践。
体会到链表在动态内存管理和灵活操作方面的优势。
(二)栈和队列的应用1、栈的实现与应用用数组和链表分别实现栈,并通过表达式求值的例子,展示了栈在计算中的作用。
2、队列的实现与应用实现了顺序队列和循环队列,通过模拟银行排队的场景,理解了队列的先进先出特性。
(三)树和二叉树1、二叉树的遍历实现了先序、中序和后序遍历算法,并对不同遍历方式的结果进行了分析和比较。
2、二叉搜索树的操作构建了二叉搜索树,实现了插入、删除和查找操作,了解了其在数据快速查找和排序中的应用。
(四)图的表示与遍历1、邻接矩阵和邻接表表示图分别用邻接矩阵和邻接表来表示图,并比较了它们在存储空间和操作效率上的差异。
2、图的深度优先遍历和广度优先遍历实现了两种遍历算法,并通过对实际图结构的遍历,理解了它们的应用场景和特点。
(五)排序算法的性能比较1、常见排序算法的实现实现了冒泡排序、插入排序、选择排序、快速排序和归并排序等常见的排序算法。
2、算法性能分析通过对不同规模的数据进行排序实验,比较了各种排序算法的时间复杂度和空间复杂度。
四、实验过程及结果(一)线性表1、顺序表在顺序表的插入操作中,如果在表头插入元素,需要将后面的元素依次向后移动一位,时间复杂度为 O(n)。
删除操作同理,在表头删除元素时,时间复杂度也为 O(n)。
线性表

2.1 线性表的类型定义
例3:下图为10个个学生的成绩表,它也是一个 线性表,该线性表的数据元素类型为结构体类型。
2.1 线性表的类型定义
从以上例子可看出线性表的逻辑特征是: 在非空的线性表中,有且仅有一个被称作 “第一个”的数据元素a1,它没有直接前趋, 而仅有一个直接后继a2; 有且仅有一个被称作“最后一个”的数据元 素an,它没有直接后继,而仅有一个直接前 趋 a n-1; 其余的数据元素ai(2≦i≦n-1)都有且仅有一个 直接前趋a i-1和一个直接后继a i+1。 线性表是一种典型的线性结构。
2.2 线性表的顺序表示和实现
#define MAXNUM 100 Elemtype List1[MAXNUM] ; /*定义线性表L1*/ int length1;
Elemtype List2[MAXNUM] ; /*定义线性表L1*/ int length2;
Elemtype List3[MAXNUM] ; /*定义线性表L1*/ int length3;
2.2 线性表的顺序表示和实现
而只需要将数组和表长封装在一个结构体中,然 后定义三个结构体变量即可: struct L_list { Elemtype List[MAXNUM]; int length; }; struct L_list L1, L2, L3; /*定义三个线性表L1,L2,L3*/
2.1 线性表的类型定义
例1:26个英文字母组成的字母表 (A,B,C、…、Z) 例2:某公司2000年每月产值表(单位:万元) (400,420,500,…,600,650) 是一个长度为12的线性表。
上述两例中的每一个数据元素都是不可分割的, 在一些复杂的线性表中,每一个数据元素又可 以由若干个数据项组成。
408考纲

一、线性表(一)线性表的定义和基本操作(二)线性表的实现1.顺序存储2.链式存储3.线性表的应用二、栈、队列和数组(一)栈和队列的基本概念(二)栈和队列的顺序存储结构(三)栈和队列的链式存储结构(四)栈和队列的应用(五)特殊矩阵的压缩存储三、树与二叉树(一)树的基本概念(二)二叉树1.二叉树的定义及其主要特征2.二叉树的顺序存储结构和链式存储结构3.二叉树的遍历4.线索二叉树的基本概念和构造(三)树、森林1.树的存储结构2.森林与二叉树的转换3.树和森林的遍历(四)树与二叉树的应用1.二叉排序树2.平衡二叉树3.哈夫曼(Huffman)树和哈夫曼编码四、图(一)图的基本概念(二)图的存储及基本操作1.邻接矩阵法2.邻接表法3.邻接多重表、十字链表(三)图的遍历1.深度优先搜索2.广度优先搜索(四)图的基本应用1.最小(代价)生成树2.最短路径3.拓扑排序4.关键路径五、查找(一)查找的基本概念(二)顺序查找法(三)分块查找法(四)折半查找法(五)B树及其基本操作、B+树的基本概念(六)散列(Hash)表(七)字符串模式匹配(八)查找算法的分析及应用六、排序(一)排序的基本概念(二)插入排序1.直接插入排序2.折半插入排序(三)起泡排序(BubbleSort)(四)简单选择排序(五)希尔排序(ShellSort)(六)快速排序(七)堆排序(八)二路归并排序(MergeSort)(九)基数排序(十)外部排序(十一)各种排序算法的比较(十二)排序算法的应用一、计算机系统概述(一)计算机发展历程(二)计算机系统层次结构1.计算机系统的基本组成2.计算机硬件的基本组成3.计算机软件和硬件的关系4.计算机系统的工作过程(三)计算机性能指标吞吐量、响应时间,CPU时钟周期、主频、CPI、CPU执行时间,MIPS、MFLOPS、GFLOPS、TFLOPS、PFLOPS。
二、数据的表示和运算(一)数制与编码1.进位计数制及其相互转换2.真值和机器数3.BCD码4.字符与字符串5.校验码(二)定点数的表示和运算1.定点数的表示无符号数的表示,带符号整数的表示。
线性表

线性表的ADT定义为:
ADT List {
数据对象:D={ ai | ai∈ElemSet, i=1,2,…,n, n≥0}
数据关系:R={< ai-1, ai >| ai-1, ai ∈ElemSet,i=1,2,…,n} 基本操作: InitList( & L) //建立(初始化)线性表
DestroyList( &L ) //销毁线形表L
张三
李四 王五 赵六 ……..
男
女 男 男 …….
18
20 21 17 …….
端州
四会 广州 端州 …….
线性表的逻辑特征是:
①在非空的线性表,有且仅有一个开始元 素a1,它没有直接前趋,而仅有一个直接后继a2 ②有且仅有一个终端元素an,它没有直接后 继,而仅有一个直接前趋an-1; ③其余的内部元素ai(2<=i<=n-1)都有且仅有 一个直接前趋 ai-1 和一个直接后继 ai+1。
算法2.1
例2. 巳知线性表LA和线性表LB中的数据元
素按值非递减有序排列,现要求将LA和LB归并 为一个新的线性表LC,且LC中的元素仍按值非 递减有序排列。 如: LA={ 3,5,8,11 }, LB={2,6,8,9,11,15 ,20}, 则结果 LC={2,3,5,6,8,8,9,11,11,15,20}
#define List_Increment 30 //追加分配长度
在顺序表存储结构中,很容易实现线性表的操作,
如:线性表的构造、第i个元素的访问、求表长等操作。
要访问某个元素也很方便,这是顺序存储的最大优
点——随机访问 注意:在C语言中的数组下标从“0”开始,因此,若L 是Sqlist类型的顺序表,则表中第i个元素是L.data[i-1]。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一、线性表的实现及操作(一)一、实验目的了解和掌握线性表的顺序存储结构;掌握用C语言上机调试线性表的基本方法;掌握线性表的基本操作:插入、删除、查找以及线性表合并等运算在顺序存储结构和存储结构上的运算,以及对相应算法的性能分析。
二、实验要求给定一段程序代码,程序代码所完成的功能为:(1)建立一个线性表;(2)依次输入数据元素1,2,3,4,5,6,7,8,9,10;(3)删除数据元素5;(4)依次显示当前线性表中的数据元素。
假设该线性表的数据元素个数在最坏情况下不会超过100个,要求使用顺序表。
程序中有3处错误的地方,有标识,属于逻辑错误,对照书中的代码仔细分析后,要求同学们修改错误的代码,修改后上机调试得到正确的运行结果。
(1)需求分析:这份实验报告为所有必做题的实验报告。
包括实验一顺序表建立、插入、删除等基本操作,实验二单链表的建立、插入、删除等基本操作,实验四二叉树的基本操作:树的建立、前序、中序、后序遍历及实验六图的遍历:深度优先和广度优先。
这四份基础性的实验为改错性质,将每个实验题目中的错误改正过来并通过调试,有助于对基础知识的理解与强化记忆。
(2)概要设计:实验一为对顺序线性表实现插入,删除,查找等基本操作。
需要用到的语句包括void ListInitiate(SeqList *L)int ListInsert(SeqList *L, int i, DataType x)int ListDelete(SeqList *L, int i, DataType *x) int ListGet(SeqList L, int i, DataType *x)等。
实验二是对单链表进行建立,插入,删除等基本操作。
需要的语句为void ListInitiate(SeqList *L)int ListInsert(SeqList *L, int i, DataType x)int ListDelete(SeqList *L, int i, DataType *x)int ListGet(SeqList L, int i, DataType *x)等。
实验四为二叉树,要求建立一个二叉树,并实现前序,中序及后序的遍历。
所需语句包括void ListInitiate(SeqList *L)int ListInsert(SeqList *L, int i, DataType x)int ListDelete(SeqList *L, int i, DataType *x)int ListGet(SeqList L, int i, DataType *x)等。
实验六的容是图的遍历包括邻接矩阵和邻接链表两种方法。
三、程序代码(更正后的代码)#include <stdio.h>#define MaxSize 100typedef int DataType;typedef struct{DataType list[MaxSize];int size;} SeqList;void ListInitiate(SeqList *L) /*初始化顺序表L*/{L->size = 0; /*定义初始数据元素个数*/ }int ListLength(SeqList L) /*返回顺序表L的当前数据元素个数*/{return L.size;}int ListInsert(SeqList *L, int i, DataType x)/*在顺序表L的位置i(0 ≤ i ≤ size)前插入数据元素值x*//*插入成功返回1,插入失败返回0*/{int j;if(L->size >= MaxSize){printf("顺序表已满无法插入! \n");return 0;}else if(i < 0 || i > L->size ){printf("参数i不合法! \n");return 0;}else{for(j = L->size; j > i; j--) L->list[j] = L->list[j];/*为插入做准备*/L->list[i] = x; /*插入*/L->size ++; /*元素个数加1*/return 1;}int ListDelete(SeqList *L, int i, DataType *x)/*删除顺序表L中位置i(0 ≤ i ≤ size - 1)的数据元素值并存放到参数x中*//*删除成功返回1,删除失败返回0*/{int j;if(L->size <= 0){printf("顺序表已空无数据元素可删! \n");return 0;}else if(i < 0 || i > L->size-1){printf("参数i不合法");return 0;}else{//此段程序有一处错误*x = L->list[i]; /*保存删除的元素到参数x中*/for(j = i +1; j <= L->size-1; j++) L->list[j] = L->list[j-1];/*依次前移*/L->size--; /*数据元素个数减1*/return 1;}}int ListGet(SeqList L, int i, DataType *x)/*取顺序表L中第i个数据元素的值存于x中,成功则返回1,失败返回0*/ {if(i < 0 || i > L.size-1){printf("参数i不合法! \n");return 0;}else{*x = L.list[i];return 1;}}void main(void){ SeqList myList;int i , x;ListInitiate(&myList);for(i = 0; i < 10; i++)ListInsert(&myList, i, i+1);ListDelete(&myList, 4, &x);for(i = 0; i < ListLength(myList); i++){ListGet( myList, i, &x); //此段程序有一处错误printf("%d ", x);}}测试结果:线性表的实现及操作(二)一、实验目的了解和掌握线性表的链式存储结构;掌握用C语言上机调试线性表的基本方法;掌握线性表的基本操作:插入、删除、查找以及线性表合并等运算在顺序存储结构和存储结构上的运算,以及对相应算法的性能分析。
二、实验要求给定一段程序代码,程序代码所完成的功能为:(1)建立一个线性表;(2)依次输入数据元素1,2,3,4,5,6,7,8,9,10;(3)删除数据元素5;(4)依次显示当前线性表中的数据元素。
假设该线性表的数据元素个数在最坏情况下不会超过100个,要求使用单链表。
程序中有3处错误的地方,有标识,属于逻辑错误,对照书中的代码仔细分析后,要求同学们修改错误的代码,上机调试并得到正确的运行结果。
三、程序代码:(更正后的结果)#include <stdio.h> /*该文件包含pringtf()等函数*/ #include <stdlib.h> /*该文件包含exit()等函数*/ #include <malloc.h> /*该文件包含malloc()等函数*/typedef int DataType; /*定义DataType为int*/typedef struct Node{DataType data;struct Node *next;} SLNode;void ListInitiate(SLNode **head) /*初始化*/{/*如果有存空间,申请头结点空间并使头指针head指向头结点*/if((*head = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);(*head)->next = NULL; /*置链尾标记NULL */}int ListLength(SLNode *head){SLNode *p = head; /*p指向首元结点*/ int size = 0; /*size初始为0*/while(p->next != NULL) /*循环计数*/{p = p->next;size ++;}return size;}int ListInsert(SLNode *head, int i, DataType x)/*在带头结点的单链表head的数据元素ai(0 ≤ i ≤ size)结点前*//*插入一个存放数据元素x的结点*/{SLNode *p, *q;int j;p = head; /*p指向首元结点*/j = -1; /*j初始为-1*/while(p->next != NULL && j < i - 1)/*最终让指针p指向数据元素ai-1结点*/{p = p->next;j++;}if(j != i - 1){printf("插入位置参数错!");return 0;}/*生成新结点由指针q指示*/if((q = (SLNode *)malloc(sizeof(SLNode))) == NULL) exit(1);q->data = x;//此段程序有一处错误p->next = q->next; /*给指针q->next赋值*/p->next = q; /*给指针p->next重新赋值*/ return 1;}int ListDelete(SLNode *head, int i, DataType *x)/*删除带头结点的单链表head的数据元素ai(0 ≤ i ≤ size - 1)结点*//*删除结点的数据元素域值由x带回。
删除成功时返回1;失败返回0*/{SLNode *p, *s;int j;p = head; /*p指向首元结点*/j = -1; /*j初始为-1*/while(p->next != NULL && p->next->next!= NULL && j < i - 1)/*最终让指针p指向数据元素ai-1结点*/{p = p->next;j++;}if(j != i - 1){printf("插入位置参数错!");return 0;}//此段程序有一处错误s = p->next; /*指针s指向数据元素ai结点*/*x = s->data; /*把指针s所指结点的数据元素域值赋予x*/ p->next = s->next; /*把数据元素ai结点从单链表中删除指*/free(s); /*释放指针s所指结点的存空间*/return 1;}int ListGet(SLNode *head, int i, DataType *x)/*取数据元素ai和删除函数类同,只是不删除数据元素ai结点*/{SLNode *p;int j;p = head;j = -1;while(p->next != NULL && j < i){p = p->next; j++;}if(j != i){printf("取元素位置参数错!");return 0;}//此段程序有一处错误*x = p->data;return 1;}void Destroy(SLNode **head){SLNode *p, *p1;p = *head;while(p != NULL){p1 = p;p = p->next;free(p1);}*head = NULL;}void main(void){SLNode *head;int i , x;ListInitiate(&head); /*初始化*/for(i = 0; i < 10; i++){if(ListInsert(head, i, i+1) == 0) /*插入10个数据元素*/{printf("错误! \n");return;}}if(ListDelete(head, 4, &x) == 0) /*删除数据元素5*/{printf("错误! \n");return;}for(i = 0; i < ListLength(head); i++){if(ListGet(head, i, &x) == 0) /*取元素*/{printf("错误! \n");return;}else printf("%d ", x); /*显示数据元素*/ }Destroy(&head);}测试结果为:.. ... . . .。