线性表ADT的顺序存储与链式存储实验报告
实验报告

实验报告课题名称:数据结构与算法班级:09网络工程姓名:杨益良学号:2009181105指导老师:梁海丽实验一:线性表的顺序存储一、实验目的1.掌握用C语言调试程序的基本方法。
2.掌握线性表顺序存储的基本运算,如插入、删除等。
二、实验内容线性表在顺序存储结构上的插入元素,删除元素运算三、实验要求1.C++/C完成算法设计和程序设计并上机调试通过。
2.撰写实验报告,提供实验结果和数据。
3.分析算法,要求给出具体的算法分析结果,并简要给出算法设计小结和心得。
四、源程序#include<stdio.h>#define MAXSIZE 100int list[MAXSIZE];int n;/*insert in a seqlist*/int sq_insert(int list[], int *p_n, int i, int x){int j;if (i<0 || i>*p_n) return(1);if (*p_n==MAXSIZE) return(2);for (j=*p_n+1; j>i; j--)list[j]=list[j-1];list[i]=x;(*p_n)++;return(0);}/*delete in a seq list*/int sq_delete(int list[], int *p_n, int i){int j;if (i<0 || i>=*p_n) return(1);for (j = i+1; j<=*p_n; j++)list[j-1] = list[j];(*p_n)--;return(0);}void main(){int i,x,temp;printf("please input the number for n\n");printf("n=");scanf("%d",&n);for (i=0; i<=n; i++){printf("list[%d]=",i);scanf("%d",&list[i]);}printf("The list before insertion is\n");for (i=0; i<=n; i++) printf("%d ",list[i]);printf("\n");printf("please input the position where you want to insert a value\nposition=");scanf("%d",&i);printf("please input the value you want to insert.\nx=");scanf("%d",&x);temp=sq_insert(list,&n,i,x);switch(temp){case 0:printf("The insertion is successful!\n");printf("The list is after insertion is\n");for(i=0; i<=n; i++) printf("%d ",list[i]);printf("\n");printf("%d\n",n);break;case 1:case 2:printf("The insertion is not successful!\n");break;}/*deleting*/printf("The list before deleting is\n");for (i=0; i<=n; i++) printf("%d ",list[i]);printf("\n");printf("please input the position where you want to delete a value\nposition=");scanf("%d",&i);temp=sq_delete(list,&n,i);switch(temp){case 0:printf("The deleting is successful!\n");printf("The list is after deleting is\n");for(i=0; i<=n; i++) printf("%d ",list[i]);printf("\n");printf("%d",n);break;case 1:printf("The deleting is not successful!");break;}}五、程序运行情况六、实验结果分析在顺序表中插入一个元素后,插入位置及之后的元素后移表长增长1;在顺序表中删除一个元素后,插入位置及之前的元素左移,表长减1;在该实验通过c语言调试程序了解并掌握了线性表在顺序存储结构上插入元素、删除元素的算法设计及相关程序设计和实现方法。
数据结构实验报告1线性表的顺序存储结构

数据结构实验报告1线性表的顺序存储结构数据结构实验报告1线性表的顺序存储结构第一章引言线性表是计算机中最常见的数据结构之一,它是一种有序的数据元素集合,其中的数据元素之间具有一对一的关系。
线性表的存储结构有多种方式,其中顺序存储结构是最简单的一种,它使用一段连续的存储单元来存储线性表中的元素。
第二章顺序存储结构的定义顺序存储结构是将线性表中的元素按照其逻辑顺序依次存储在一块连续的存储空间中。
顺序存储结构的特点是可以快速地访问任意位置的元素,但插入和删除操作需要移动大量的元素。
第三章顺序存储结构的实现1.存储空间的分配顺序存储结构通常使用数组来实现,数组的长度应该大于等于线性表的长度,以防止溢出。
存储空间的分配可以使用静态分配或动态分配两种方式来实现。
2.线性表的初始化初始化线性表时,需要设置线性表的长度和当前元素的个数。
3.线性表的增删改查操作●插入操作:________在指定位置插入一个元素时,需要将插入位置之后的元素依次后移,给待插入的元素腾出位置。
●删除操作:________删除指定位置的元素时,需要将删除位置之后的元素依次前移,覆盖删除位置上的元素。
●修改操作:________修改指定位置的元素时,直接对该位置上的元素进行修改即可。
●查找操作:________根据指定的元素值,查找其在顺序存储结构中的位置。
4.线性表的遍历操作遍历操作可以按照顺序访问线性表中的每个元素,可以使用循环结构实现遍历操作。
第四章顺序存储结构的优缺点分析1.优点:________可以快速地访问任意位置的元素,节省存储空间。
2.缺点:________插入和删除操作需要移动大量的元素,不适用于频繁插入和删除的场景。
第五章实验过程和结果分析在本次实验中,我们以顺序存储结构为基础,实现了线性表的增删改查操作,并进行了遍历操作。
通过实验,我们发现顺序存储结构在查询操作上有较好的性能,但在插入和删除操作上的性能较差。
第六章附件本文档涉及的附件详见附件文件。
数据结构实验报告总结

数据结构实验报告总结本次数据结构实验主要涉及到线性表、栈和队列的基本操作,通过实验操作和总结,我对数据结构的相关知识有了更深入的理解和掌握。
首先,我们进行了线性表的实验操作。
线性表是一种数据结构,它是由n(n≥0)个数据元素组成的有限序列。
在实验中,我们学习了线性表的顺序存储结构和链式存储结构。
通过代码实现,我深刻理解了顺序表和链表的存储方式和特点。
在实验过程中,我发现顺序表适合查找操作,而链表适合插入和删除操作。
这让我对线性表的应用场景有了更清晰的认识。
其次,我们进行了栈的实验操作。
栈是一种特殊的线性表,它只能在表的一端进行插入和删除操作。
在实验中,我学习了栈的基本操作,包括入栈和出栈。
通过实际操作,我深刻理解了栈的“先进后出”的特性,以及它在计算机程序设计中的应用。
我发现栈在递归算法、表达式求值和括号匹配等方面有着重要的作用,这让我对栈的实际应用有了更深入的认识。
最后,我们进行了队列的实验操作。
队列是一种特殊的线性表,它只能在表的一端进行插入操作,而在另一端进行删除操作。
在实验中,我学习了队列的基本操作,包括入队和出队。
通过实际操作,我深刻理解了队列的“先进先出”的特性,以及它在计算机程序设计中的重要性。
我发现队列在广度优先搜索、模拟系统等方面有着重要的应用,这让我对队列的实际应用有了更深入的了解。
通过本次数据结构实验,我不仅掌握了线性表、栈和队列的基本操作,还深刻理解了它们在实际应用中的重要性。
我相信这些知识和经验对我的学习和工作都将有着重要的帮助。
在未来的学习和实践中,我将继续加强对数据结构的理解和运用,不断提升自己的编程能力和解决问题的能力。
总之,本次数据结构实验让我受益匪浅,我将继续努力学习和实践,不断提升自己的专业能力。
希望通过不懈的努力,能够在数据结构领域取得更大的成就。
数据结构实验报告-3-线性表的顺序存储-1

//析构函数为空
int Length();
//求线性表的长度
datatype Get(int i);
//按位查找,取线性表的第 i 个元素
int Locate(datatype item); //查找元素 item
void Insert(int i, datatype item); //在第 i 个位置插入元素 item
cout<<"溢出"<<endl; } if (i<1 || i>length+1) {
cout<<"i 不合法!"<<endl; } for (j=length; j>=i; j--)
data[j]=data[j-1]; data[i-1]=item; length++; } //(5)删除线性表中第 i 个元素算法 /* *输 入:要删除元素位置 i *前置条件:顺序表存在,i 要合法 *功 能:删除顺序表中位置为 i 的元素 *输 出:无 *后置条件: 顺序表册除了一个元素,表长减 1 */ //实现代码: template <class datatype> datatype SeqList<datatype>::Delete(int i) { int item,j; if (length==0) {
cout<<"表为空,无法删除元素!"<<endl; } if (i<1 || i>length)
{ cout<<"i 不合法!"<<endl;
} item=data[i-1];//获得要删除的元素值 for (j=i; j<length; j++)
数据结构实验报告-线性表的顺序存储

姓 名
专业班级
实验地点
指导教师
实验时间
一、实验目的及要求
本次实验目的是通过上机练习,熟悉和掌握课堂所讲授的基本知识点。要求上机以前要认真复习课堂教学内容。完成教师带领实验,完成线性表的顺序存储实验。
二、实验设备(环境)及要求
计算机;学生不许把食物带到机房吃;不许上网做与实验无关的内容;不许同学之间聊天;保持实验室安静卫生。下课把键盘,座椅放回原处。
Integer length;/*当前线性表长度,线性表中现有元素个数*/
Integer listsize;/*当前分配的存储量以下定义线性表的操作*/
Integer InitList(Class_List *SqList)
/*构造一个空的线性表*/
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int Integer;
typedef char *String;
typedef struct
{
Integer number;
String name[10];
Integer age;
String interest[50];
完成一个有多于3个学生的线性表。并且显示学生信息。删除其中一个学生。然后再打印显示。
Source.cpp
#include"header.h"
void main()
{
Class_List xinji2013;
InitList(&xinji2013);
Student st;
Integer i,n=2,w,q,e;
三、实验内容与步骤
实验报告 线性表的顺序存储结构

学院: 专业: 班级:
姓名
学号
实验组
实验时间
指导教师
成绩
实验项目名称实验一 线性Fra bibliotek的顺序存储结构
实验目的
1、 熟练掌握线性表的基本操作在顺序存储与链式存储上的实现;
2、 以线性表的各种操作(建立、插入、删除等)的实现为重点;
3、 掌握线性表的动态分配顺序存储结构的定义与基本操作的实现;
if(pos<1||pos>l、size+1)
{
cout<<"插入的位置非法!"<<endl;
return false;
}
if(l、size==l、maxsize)
{
int k=sizeof(Elemtype);
l、elem=(Elemtype *)realloc(l、elem,2*l、maxsize*k);
insertlist(k,a[i],i+1);
traverselist(k);
cout<<"插入一个位置:"<<endl;
cin>>x;
cout<<endl;
insertlist(k,0,x);
traverselist(k);
cout<<"插入一个元素:"<<endl;
cin>>x;
cout<<endl;
if(l、elem==NULL)
{
cout<<"分配空间不成功!"<<endl;
return false;
数据结构线性表实验报告

数据结构线性表实验报告数据结构线性表实验报告引言:数据结构是计算机科学中的一个重要概念,它研究如何组织和存储数据,以便能够高效地访问和操作。
线性表是数据结构中最基本的一种,它是一种有序的数据元素集合,其中的元素之间存在一对一的关系。
本次实验旨在通过实际操作线性表,加深对数据结构的理解,并掌握基本的线性表操作。
实验目的:1. 理解线性表的概念和特点;2. 掌握线性表的基本操作,如插入、删除、查找等;3. 熟悉线性表的顺序存储结构和链式存储结构;4. 分析不同存储结构的优缺点。
实验内容:1. 实现线性表的顺序存储结构顺序存储结构是将线性表的元素按照其逻辑顺序依次存放在一块连续的存储空间中。
我们可以使用数组来实现顺序存储结构。
首先,定义一个固定大小的数组作为线性表的存储空间,然后通过数组的下标来访问和操作线性表中的元素。
在插入和删除元素时,需要移动其他元素的位置,以保持线性表的有序性。
2. 实现线性表的链式存储结构链式存储结构是将线性表的元素存储在一系列的结点中,每个结点包含一个数据元素和一个指向下一个结点的指针。
通过将各个结点用指针连接起来,形成一个链表。
在插入和删除元素时,只需要修改相邻结点之间的指针,而不需要移动其他元素的位置。
实验步骤:1. 实现顺序存储结构的线性表首先,定义一个固定大小的数组,用于存储线性表的元素。
然后,实现插入、删除、查找等基本操作。
在插入元素时,需要判断线性表是否已满,如果已满则需要扩容。
在删除元素时,需要判断线性表是否为空,如果为空则无法删除元素。
通过实现这些基本操作,可以对线性表进行增删查改等操作。
2. 实现链式存储结构的线性表首先,定义一个结点类,包含一个数据元素和一个指向下一个结点的指针。
然后,通过将各个结点用指针连接起来,形成一个链表。
实现插入、删除、查找等基本操作。
在插入元素时,需要找到插入位置,并修改相邻结点之间的指针。
在删除元素时,需要找到待删除元素的前一个结点,并修改前一个结点的指针。
线性表实验报告

线性表实验报告一、实验目的本次实验的主要目的是深入理解线性表的基本概念和操作,通过实际编程实现线性表的存储和基本运算,掌握线性表在数据结构中的应用,提高对数据结构的理解和编程能力。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验原理线性表是一种最基本、最简单的数据结构,它是由 n(n≥0)个数据元素组成的有限序列。
在这个序列中,每个数据元素的位置是按照其逻辑顺序排列的。
线性表有两种存储结构:顺序存储结构和链式存储结构。
顺序存储结构是用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的两个元素在物理位置上也相邻。
其优点是可以随机访问表中的任意元素,时间复杂度为 O(1);缺点是插入和删除操作需要移动大量元素,时间复杂度为 O(n)。
链式存储结构是通过指针将各个数据元素链接起来,每个数据元素由数据域和指针域组成。
其优点是插入和删除操作不需要移动大量元素,时间复杂度为 O(1);缺点是不能随机访问表中的元素,需要从头指针开始遍历,时间复杂度为 O(n)。
四、实验内容本次实验实现了顺序表和链表的基本操作,包括创建、插入、删除、查找、遍历等。
1、顺序表的实现定义顺序表的结构体,包括数据存储数组和表的长度。
实现顺序表的初始化函数,将表的长度初始化为 0。
实现顺序表的插入函数,在指定位置插入元素,如果插入位置非法或表已满,则返回错误。
实现顺序表的删除函数,删除指定位置的元素,如果删除位置非法,则返回错误。
实现顺序表的查找函数,查找指定元素,如果找到则返回元素的位置,否则返回-1。
实现顺序表的遍历函数,输出表中的所有元素。
2、链表的实现定义链表的结构体,包括数据域和指向下一个节点的指针域。
实现链表的创建函数,创建一个空链表。
实现链表的插入函数,在指定位置插入元素,如果插入位置非法,则返回错误。
实现链表的删除函数,删除指定位置的元素,如果删除位置非法,则返回错误。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告题目:完成线性表ADT的顺序存储和链式存储方式的实现一、需求分析1、本演示程序中,线性表的数据元素类型限定为整型2、演示程序以用户和计算机的对话方式执行,即在计算机的终端上显示“提示信息”之后由用户在键盘上键入演示程序规定的运算命令,相应的输出结果显示在后面。
3、程序的执行命令包括:创建、撤销、清空、插入、修改、删除、定位等线性表ADT各项基本操作二、概要设计为实现上述功能,我们给出线性表的抽象数据类型定义,具体的有单向链,双向链,顺序表等,同时对于上述功能的实现还采用有/无头结点两种方式来实现1.线性表的抽象数据类型定义为ADT List{数据对象:D={a i|a i∈ElemSet,i=1,2,…,n,n≥0}数据关系:R1={<a i-1,a i>|ai-1,ai∈D,i=2,…,n}基本操作:InitList(&L)操作结果:构造一个空的线性表LDestroyList(&L)初始条件:线性表L已存在。
操作结果:销毁线性表L。
ClearList(&L)初始条件:线性表L已存在。
操作结果:将L重置为空表。
ListEmpty(L)初始条件:线性表L已存在。
操作结果:若L为空表,则返回TRUE,否则返回FALSE。
ListLength(L)初始条件:线性表L已存在。
操作结果:返回L中的i个数据元素的值。
GetElem(L,i,&e)初始条件:线性表L已存在,1≤i≤ListLength(L)。
操作结果:用e返回L中第i个数据元素的值。
LocateElem(L,e,compare())初始条件:线性表L已存在,compare()是数据元素判定函数操作结果:返回L中第一个与e满足compare()的数据元素的位序。
若这样的数据元素不存在,则返回值为0.PriorElem(L,cur_e,&pre_e)初始条件:线性表已存在操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
NextElem(L,cur_e,&next_e)初始条件:线性表L已存在操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
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。
ListTraverse(L,visit())初始条件:线性表L已存在。
操作结果:依次对L的每一个数据元素调用函数visit(),一旦visit()失败,则操作失败。
}ADT List2.主程序包括三个模块:1)主程序模块:void main(){初始化;do{接受命令;处理命令;}while(“命令”=“继续执行”);}2)有序表单元模块——实现有序表的抽象数据类型;3)节点结构单元模块——定义有序表的节点结构。
各模块之间的调用关系如下:主程序模块有序表单元模块节点结构单元模块三、详细设计1.本程序中一些常见的预定义#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;//Status 是函数的类型,其值是函数结果状态代码typedef int bool;//bool是布尔类型,其值是TRUE或FALSE 2.单向链表有头结点的ADT实现(伪代码表示)1)元素类型,节点类型和指针类型typedefint ElemType; //元素类型typedefstruct NodeType{ElemType data;NodeType *next;}NodeType,*LinkType; //节点类型,指针类型2)部分基本操作的实现Status InitList(List &L){//构造一个空的线性表//头节点存放的数据元素是该链的长度,初始为0p=(LinkType)malloc(sizeof(NodeType));if(!p) return FALSE;p->data=0;//当前链表元素个数为0p->next=NULL;L_head=p;return TRUE;}//InitListvoid DestroyList(List &L){//将线性表L销毁´p=L_head;while(p!=NULL){q=p->next;free(p);p=q;}}//DestroyListvoid ClearList(List &L){//将线性表L重置为空表p=L_head->next;//头节点不能被释放掉while(p!=NULL){q=p->next;free(p);p=q;}L_head->data=0;//空表的数据元素个数又被置为0 }//ClearListbool ListEmpty(L){//判断L是否为空表,是则返回TRUE,否则返回FALSE p=L_head->next;if(!p)return TRUE;elsereturn FAlSE;}ListEmptyint ListLength(L){//返回L中的数据元素个数p=L_head->next;i=0;while(p){p=p->next;i++;}return i;}//ListLengthstatus GetElem(List L,int i,ElemType &e)//用e返回L中第i个数据元素的值{p=L.head->next;j=1;while(p&&j<i){p=p->next;j++;}//找到第i个节点,并用p指向它if(!p||j>i)return error; //输入的i不合法或L为空表e=p->data;}//GetElemint LocateElem(List L,ElemType e,compare())//返回L中第一个与e满足关系compare()的数据元素位序//若这样数据元素不存在返回0//当关系满足时Àcompare()返回1,否则返回{p=L.head->next;i=1;while(p&&!compare(p->data,e)){p=p->next;i++;}//找到第一个与e满足compare()关系的数据元素位置if(p==NULL)return 0;//不存在这样的数据元素?elsereturn i;}//LocateElemstatus PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e)//用pre_e返回cur_e的前驱{p=L_head;while(p->next&&p->next->data!=cur_e)p=p->next;if(!p->next)return error; //操作失败¹pre_e=p;return OK;}//PriorElemstatus NextElem(LinkList L,ElemType cur_e,ElemType &next_e)//用next_e返回cur_e的后继{p=L.head->next;while(p&&p->data!=cur_e)p=p->next;if(p&&p->next)//找到数据元素为cur_e的节点,且不是最后一个元素{next_e=p->next;return OK;}elsereturn error;}//NextElem_Lstatus ListInsert(List &L,int i,ElemType e)//在线性表L的第i个位置前插入新的数据元素e,L的长度加¨1{p=L.head;j=0;while(p&&j<i-1){p=p->next;j++;}//找到第i-1个节点if(!p||j>i-1)return error; //输入的i不合法s=(LinkType)malloc(sizeof(NodeType));//生成一个新的节点s->data=e;s->next=p->next;p->next=s; //将节点插入链表中 L_head->data++; //链表长度加1return OK;}//ListInsertstatus ListDelete(List &L,int i,ElemType &e)//删除L中第i个数据元素,并用e返回其值,L的长度减1{p=L_head;j=0;while(p->next&&j<i-1){p=p->next;j++;}//找到第i-1个节点if(!(p->next)||j>i-1)return error; //输入的i不合法q=p->next;p->next=q->next;e=q->data;free(q); //删除且释放第i个节点,并返回其数据值L_head->data--;//链表长度减去1return OK;}//ListDletestatus ListTraverse(List L,visit())//对L的每个元素调用visit()//visit()函数每成功|一次就返回1,否则返回0{p=L_head->next;while(p){if(visit(p))p=p->next;elsebreak;}if(!p)return OK;//调用失败¹elsereturn error;}//ListTraverse3.单向链无头结点的ADT实现(伪代码表示)1)元素类型,节点类型和指针类型typedefint ElemType; //元素类型typedefstruct NodeType{ElemType data;NodeType *next;}NodeType,*LinkType; //节点类型,指针类型3)部分基本操作的实现Status InitList(List &L){//构造一个空的线性表p=(LinkType)malloc(sizeof(NodeType));if(!p) return FALSE;p->data=e;//放入第一个数据元素p->next=NULL;L_head=p;return TRUE;}//InitListvoid DestroyList(List &L){//将线性表L销毁´p=L_head;while(p!=NULL){q=p->next;free(p);p=q;}}//DestroyListbool ListEmpty(L){//判断L是否为空表,是则返回TRUE,否则返回FALSE p=L_head;if(!p)return TRUE;elsereturn FAlSE;}//ListEmptyint ListLength(L){//返回L中的数据元素个数p=L_head;i=0;while(p){p=p->next;i++;}return i;}//ListLengthstatus GetElem(List L,int i,ElemType &e)//用e返回L中第i个数据元素的值{p=L.head;j=1;while(p&&j<i){p=p->next;j++;}//找到第i个节点,并用p指向它if(!p||j>i)return error; //输入的i不合法或L为空表e=p->data;}//GetElemint LocateElem(List L,ElemType e,compare())//返回L中第一个与e满足关系compare()的数据元素位序//若这样数据元素不存在返回0//当关系满足时Àcompare()返回1,否则返回{p=L.head;i=1;while(p&&!compare(p->data,e)){p=p->next;i++;}//找到第一个与e满足compare()关系的数据元素位置if(p==NULL)return 0;//不存在这样的数据元素?elsereturn i;}//LocateElemstatus PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e) //用pre_e返回cur_e的前驱{p=L_head;while(p->next&&p->next->data!=cur_e)p=p->next;if(!p->next)return error; //操作失败¹pre_e=p;return OK;}//PriorElemstatus NextElem(LinkList L,ElemType cur_e,ElemType &next_e) //用next_e返回cur_e的后继{p=L.head;while(p&&p->data!=cur_e)p=p->next;if(p&&p->next)//找到数据元素为cur_e的节点,且不是最后一个节点{next_e=p->next;return OK;}elsereturn error;}//NextElemstatus ListInsert(LinkList &L,int i,ElemType e)//在线性表L的第i个位置前插入新的数据元素e,L的长度加1{p=L_head;j=0;if(i==1){s=(LinkType)malloc(sizeof(NodeType));//生成一个新的节点s->data=e;s->next=p;L_head=s;return OK;}//在链表的第一个节点前插入一个节点while(p&&j<i-1){p=p->next;j++;}//找到第i-1个节点if(!p||j>i-1)return error; //输入的i不合法s=(LinkType)malloc(sizeof(LNode));//生成一个新的节点s->data=e;s->next=p->next;p->next=s; //将节点插入链表中return OK;}//ListInsertstatus ListDelete(List &L,int i,ElemType &e)//删除L中第i个数据元素,并用e返回其值¦,L的长度减1{p=L_head;j=0;if(i==1){L_head=p->next;free(p);return OK;}//删除L的第一个节点while(p->next&&j<i-1){p=p->next;j++;}//找到第i-1个节点if(!(p->next)||j>i-1)return error; //输入的i不合法q=p->next;p->next=q->next;e=q->data;free(q); //删除且释放第i个节点,并返回其数据元素值return OK;}//ListDletestatus ListTraverse(List L,visit())//对L的每个元素调用visit()//visit()函数每成功|一次就返回1,否则返回0{p=L_head;while(p){if(visit(p))p=p->next;elsebreak;}if(!p)return OK;//调用失败¹elsereturn error;}//ListTraverse3.双向链有头结点部分操作实现(伪代码表示)1)元素类型,节点类型和指针类型Typedefstruct DuLNode{int data;struct DuLNode *prior;struct DuLNode *next;}NodeType,*LinkNode;2) 部分基本操作的实现Status InitList(List &L)//创建一个空的双向线性表{p=(LinkNode)malloc(sizeof(DuLNode));if(!p)return FALSE;p->data=0; //头结点存放链表的长度,初始为0p->next=NULL;p->prior=NULL;return p;}//InitListvoid DestroyList(List &L)//销毁一个双向链表{p=q=L_head;while(p!=NULL){q=p->next;free(p);p=q;}}//DestroyListvoid ClearList(List &L)//将一个线性表置为空表{p=q=L_head->next;while(p!=NULL){q=p->next;free(p);p=q;}L_head->data=0; //空表则头结点内存放节点数据置为0 L_head->prior=NULL;L_head->next=NULL;}//ClearListint ListLength(List L)//返回双向链表的长度{i=0;p=L_head->next;while(p!=NULL){p=p->next;i++;}return i;}//ListLengthStatus ListInsert(List &L,int i,LinkNode e){q=L_head;n=1;if(i<1||i>ListLength(L_head)+1)return FALSE; //输入的i值有误elseif(i!=ListLength(L_head)+1)//在双向链的非最后一个元素前插入{while(n!=i){q=q->next;n++;}q->next->prior=e;e->next=q->next;q->next=e;e->prior=q;}else{while(q->next!=NULL)q=q->next;q->next=e;e->prior=q;e->next=NULL;}L_head->data++; //元素数目加1return OK;}//ListInsertStatus ListDelete(Link &L,int i,ElemType &e)//删除第i个节点,并用e返回其值{q=L_head->next;n=1;if(i<1||i>ListLength(L_head))return FALSE;elseif(i!=ListLength(L_head))//删除的不是最后一个节点{while(n!=i){q=q->next;n++;}q->prior->next=q->next;q->next->prior=q->prior;}else//删除的是最后一个节点{while(q->next!=NULL)q=q->next;q->prior->next=NULL;}e=q->data;free(q);L_head->data--;//数ºy据Y元a素?数ºy目?减?1return OK;}//ListDeleteint LocateElem(DuLNode *L_head,int e,int (*compare)(int a,int b)) //返回L中第一个与e满足compare()的数据元素位序,若没有则返回0//compare()函数返回值是满足该关系返¦回1,不满足返回0{p=L_head->next;i=1;while(p!=NULL&&!(*compare)(p->data,e)){p=p->next;i++;}if(p==NULL)return 0;elsereturn i;}//LocateElemStatus ListTraverse(List L,visit())//实现元素的遍历,一旦遍历失败,返回FALSE,成功返回TRUE{p=L_head;while(p!=NULL){visit(p);p=p->next;}if(p!=NULL)return FALSE;elsereturn TRUE;}//ListTraverse4.顺序表的实现(伪代码)1)部分量的定义struct SqList{int *elem; //存储空间基址int length; //当前长度int listsize; //当前分配的存储空间};#define LIST_INIT_SIZE 100//线性表存储空间的初始分配量#define LISTINCEREMENT 10 //线性表存储空间的分配增量2)部分基本操作的实现Status InitList(SqList &L)//构造一个空的线性表{L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!L.elem)exit(OVERFLOW);//存储分配失败L.length=0; //空表长度为0L.listsize=LIST_INIT_SIZE;return OK;}//InitListint LocateElem(SqList &L,int e,compare())//返回L中第一个与e满足compare()的数据元素位序,若没有则返回0 //compare()函数返回值是满足该关系返回1,不满足返回0{for(i=0;i<L.length;i++)if(compare(*(L.elem+i),e)==1)break;if(i>=L.length)return FALSE;elsereturn (i+1);}//LocateElembool GetElem(SqList *L,int i,int&e)//用e返回L中的第i个数据元素的值,成功函数返回TRUE,否则FALSE {if(i<1||i>L->length)return FALSE;e=*(L.elem+i-1);return TRUE;}//GetElemStatus ListInsert(SqList &L,int i,int e)//在线性表的第i个位置之前插入新的数据元素{if(i<1||i>L.length+1)return FALSE; //输入的i值不合法if(L.length>=L.listsize){Newbase=(int *)realloc(L->elem,(L->listsize+LISTINCEREMENT)*sizeof(int));if(!New)exit(0); //存储分配失败L->elem=New;L->listsize+=LISTINCEREMENT;//增加存储容量}//存储空间满的情况,需重新分配存储空间q=&((L->elem)[i-1]);for(p=&(L->elem)[L->length];p>=q;p--)*(p+1)=*p; //插入位置及之后的元素向后移*q=e;//插入eL->length++;return TRUE;}//ListInsertbool ListDelete(SqList &L,int i,int&e)/*删除线性表第i个元素值并用e返回/{if(i<1||i>L->length)return FALSE;//输入的i不合法p=&((L->elem)[i-1]);//待删除元素位置e=*p; //被删除的元素用e返回值q=L->elem+L->length-1;// 表尾元素的位置for(p++;p<=q;p++)//被删除元素之后的元素往前移*(p-1)=*(p);L->length--;return TRUE;}//ListDeleteStatus ListTraverse(SqList &L,visit())//对线性表元素做一个遍历{for(i=0;i<L->length;i++)visit((L->elem)[i]);if(i!=L->length)return FALSE;elsereturn TRUE;}//ListTraverse5.主函数和其他函数的伪码算法void main(){//主函数Initialization(); //初始化do{system(“cls”);//清屏cmd=Menu();//读入操作命令符Inrerpret(cmd); //解释执行操作命令符scanf(" %c",&c); //判断是否继续进行操作}while(c=='Y'||c=='y');}//mainint Menu(){//读入用户输入int a;printf("\n");printf("双向链表的功能菜单:\n");printf("1.构造一个双向链表\n");printf("2.销毁一个双向链表\n");printf("3.将一个双向链表清空\n");printf("4.得到链表中第一个与所输入数满足一定大小关系的元素的位序\n");printf("5.插入一个新的数据元素\n");printf("6.删除一个节点,并得到该节点的值\n");printf("7.遍历整个链表,打印节点数据\n");printf("请输入您要选择的操作对应的数字\n");scanf("%d",&a);return a;}Inrerpret(cmd){switch(cmd){case 1: L_head=InitList(); //构造一个空链表printf("是否继续其他操作(Y\\N)\n");scanf(" %c",&c);break;case 2: DestroyList(L_head); //销毁一个链表L_head=NULL;printf("是否继续其他操作(Y\\N)\n");scanf(" %c",&c);break;case 3: L_head=ClearList(L_head);printf("是否继续其他操作(Y\\N)\n");scanf(" %c",&c);break;case 4: do{printf("请输入一个数\n");scanf("%d",&i);k=LocateElem(L_head,i,compare);if(k==0)printf("未找到匹配compare的数据元素\n");elseprintf("链表中第一个与输入的数满足compare()(即相等)的元素位序为%d\n",k);printf("是否继续进行此项匹配操作(Y\\N)\n");scanf(" %c",&c);}while(c=='Y'||c=='y');printf("是否继续其他操作(Y\\N)\n");scanf(" %c",&c);break;case 5: do{p=(DuLNode *)malloc(sizeof(DuLNode));//创建一个待插入的节点printf("请输入待插入节点的节点数据\n");scanf("%d",&p->data);printf("请您输入您准备在链表中第几个元素前插入节点\n");scanf("%d",&i);p=ListInsert(L_head,i,p); //在链表的第i个元素前插入节点if(p==FALSE)printf("无法插入\n");elseL_head=p;printf("您是否要继续插入节点(Y\\N)\n");scanf(" %c",&c);}while(c=='Y'||c=='y');printf("是否继续其他操作(Y\\N)\n");scanf(" %c",&c);break;case 6:do{printf("请输入您要删除的数据元素在链表中的位序\n");scanf("%d",&i);e=&k;p=ListDelete(L_head,i,e);if(p==FALSE)printf("无该节点\n");else{L_head=p;printf("删除的数据元素值为%d\n",*e);}printf("是否继续删除其他节点(Y\\N)\n");scanf(" %c",&c);}while(c=='Y'||c=='y');printf("是否继续其他操作(Y\\N)\n");scanf(" %c",&c);break;case 7:k=ListTraverse(L_head,Print);//遍历并打印节点数据,其中头结点数据也被打印,表示总共数据数目if(k==FALSE)printf("遍历失败\n");elseprintf("遍历成功\n");printf("是否继续进行其他操作(Y\\N)\n");scanf(" %c",&c);break;default:printf("请重新选择功能\n");}//Interpret6.函数调用关系main()Initialization Menu InterpretListLength四、调试分析1.本程序初次设计时未加入清屏函数,使得计算机终端显示结果较为杂乱,难以看清具体操作2.本程序在开始编译时因构造结构体类型时尾端未加入分号,使得调试程序浪费了较多的时间3.在有些地方指针变量未初始化,或者未分配空间,使得程序经常崩溃,或出现一些意想不到的结果,导致修改花费了很多时间4.本次作业采用数据抽象的程序设计方法,采用多种方式实现线性表ADT的基本操作,对线性表的各项操作有了更深刻理解,同时本程序分了多个模块,使得程序的封装性较好,从而可移植性较强,调试时也显得更加简单,程序风格良好五、用户手册1、本程序的运行环境为DOS操作系统,执行文件分别为“链式存储无头点.exe”,“链式存储有头结点程序.exe”,“双向链表程序.exe”,“顺序存储.exe”2、本程序在每一次的操作结束后都会提示是否继续进行本次操作,输入Y或y均可继续进行本次操作,若想退出本次操作,输入其他字符即可,然后计算机终端会询问是否返回主菜单进行其他操作,输入Y或y返回主菜单,输入其他字符,退出本程序3、本程序的部分功能如定位,添加,删除等必须建立在进行了链表创建的基础上4、本程序的定位与遍历函数用到了两个函数指针compare和visit,需要用户自己独立书写5、接受命令后即可执行相应的运行并显示出结果六、测试结果本程序经过多组数据测试,所有操作均符合预期设想七、附录链式存储无头结点.cpp链式存储有头结点程序.cpp双向链表程序.cpp顺序存储.cpp。