链表顺序表实验报告数据结构与算法分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构与算法分析课程设计报告
课题名称: 使用一个链表和顺序表构建城市数据库
提交文档组号:提交文档组号: 2 2 编程学生姓名及学号:编程学生姓名及学号: 测试学生姓名及学号:测试学生姓名及学号: 报告学生姓名及学号:报告学生姓名及学号:
指导指导 教 师 姓 名:名: 指导教师评阅成绩:指导教师评阅成绩: 指导教师评阅意见:
. . 
提交报告时间:提交报告时间: 2013 2013 2013 年年 11 11 月月 日日
实验一:Implement a city database using unordered lists and link lists
1. 实验的目的和要求: 
<1><1>采用采用C++C++的的ASCII 码文件和模块函数实现码文件和模块函数实现; ; <2><2>熟练掌握数组列表和链表列表的实现熟练掌握数组列表和链表列表的实现熟练掌握数组列表和链表列表的实现; ;
<3><3>熟练掌握计算机系统的基本操作方法,了解如何编译、运行一个熟练掌握计算机系统的基本操作方法,了解如何编译、运行一个C++C++程序程序程序; ; <4><4>上机调试程序上机调试程序上机调试程序,,掌握查错、排错使程序能正确运行。

掌握查错、排错使程序能正确运行。

2. 实验的环境: 
1、硬件环境:索尼笔记本电脑,Intel(R) Core(TM) i7-3632M ,8GB 内存可;内存可;
2、软件环境:Windows 8 下的Microsoft Visual Studio 2008
2. 算法描述: 
数据结构与算法分析的背景:数据结构与算法分析的背景:
数据结构是计算机程序设计的重要理论技术基础,它不仅是计算机学科的核心课称,而且已成数据结构是计算机程序设计的重要理论技术基础,它不仅是计算机学科的核心课称,而且已成为其他理工专业的热门选修课。

为其他理工专业的热门选修课。

数据结构是一门专业选技术基础科。

一方面,它要求我们学会分析研究计算机加工的数据结构数据结构是一门专业选技术基础科。

一方面,它要求我们学会分析研究计算机加工的数据结构的特性,以便为应用涉及的数据选择适当的逻辑结构、存储结构及其相应的算法,并初步掌握算法的时间分析和空间分析的技术;另一方面,数据结构的学习过程也是复杂程序设计的训练过程,要求我们编写的程序结构清楚和正确易读,复合软件工程的规范,并培养我们的数据抽象能力。

本次课程设计就是对数据结构中的顺序表和链表的操作的应用。

课程设计就是对数据结构中的顺序表和链表的操作的应用。

顺序表: 1. 顺序表的定义顺序表的定义 (1) (1) 顺序存储方法顺序存储方法顺序存储方法 即把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法。

即把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法。

即把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法。

(2) (2) 顺序表(顺序表(顺序表(Sequential List Sequential List Sequential List))
用顺序存储方法存储的线性表简称为顺序表(用顺序存储方法存储的线性表简称为顺序表(用顺序存储方法存储的线性表简称为顺序表(Sequential List Sequential List Sequential List))。

2. 结点结点a a i 的存储地址的存储地址
不失一般性,设线性表中所有结点的类型相同,则每个结点所占用存储空间大小亦相同。

假设表中每个结点占用设表中每个结点占用c c 个存储单元,其中第一个单元的存储地址则是该结点的存储地址,并设表中开始结点开始结点a a 1的存储地址(简称为基地址)是的存储地址(简称为基地址)是LOC LOC LOC((a 1),那么结点,那么结点a a i 的存储地址的存储地址LOC LOC LOC((a i )可通过下式计算:计算:
LOC LOC((a i )= LOC = LOC((a 1)+(i-1i-1))*c 1*c 1≤≤i ≤n 注意:注意:
在顺序表中,在顺序表中,每个结点每个结点每个结点a a i 的存储地址是该结点在表中的位置的存储地址是该结点在表中的位置i i 的线性函数。

只要知道基地址和每个结点的大小,就可在相同时间内求出任一结点的存储地址。

是一种随机存取结构。

每个结点的大小,就可在相同时间内求出任一结点的存储地址。

是一种随机存取结构。

顺序表上实现的基本运算顺序表上实现的基本运算: : 表的初始化表的初始化;;求表长求表长;;取表中第取表中第i i 个结点个结点;;查找值为查找值为x x 的结点的结点;;插入插入 (1) 插入运算的逻辑描述插入运算的逻辑描述 线性表的插入运算是指在表的第线性表的插入运算是指在表的第i i (1≤i ≤n+1n+1)个位置上,插入一个新结点)个位置上,插入一个新结点)个位置上,插入一个新结点x x ,使长度为,使长度为n n 的线性表:性表:
((a 1,…,a i-1,a i ,…a n ) 变成长度为变成长度为n+1n+1n+1的线性表:的线性表:(a 1,…,a i-1,x ,a i ,…a n ) 注意:注意: ①① 由于向量空间大小在声明时确定,当由于向量空间大小在声明时确定,当L-L-L->>length length≥≥List Size List Size时,表空间已满,不可再做时,表空间已满,不可再做插入操作;插入操作;
② 当插入位置当插入位置i i 的值为的值为i i >n 或i <1时为非法位置,不可做正常插入操作;时为非法位置,不可做正常插入操作; (2) 顺序表插入操作过程顺序表插入操作过程
在顺序表中,结点的物理顺序必须和结点的逻辑顺序保持一致,因此必须将表中位置为在顺序表中,结点的物理顺序必须和结点的逻辑顺序保持一致,因此必须将表中位置为n n n ,,n-1n-1,…,,…,i 上的结点,依次后移到位置上的结点,依次后移到位置n+1n+1n+1,,n ,…,i+1i+1上,空出第上,空出第上,空出第i i 个位置,然后在该位置上插入新结点新结点x x 。

仅当插入位置。

仅当插入位置i=n+1i=n+1i=n+1时,才无须移动结点,直接将时,才无须移动结点,直接将时,才无须移动结点,直接将x x 插入表的末尾。

插入表的末尾。

(4)算法分析)算法分析 ① 问题的规模问题的规模 表的长度表的长度表的长度L-L-L->>length length(设值为(设值为(设值为n n )是问题的规模。

)是问题的规模。

② 移动结点的次数由表长移动结点的次数由表长n n 和插入位置和插入位置i i 决定决定 算法的时间主要花费在算法的时间主要花费在算法的时间主要花费在for for for循环中的结点后移语句上。

该语句的执行次数是循环中的结点后移语句上。

该语句的执行次数是循环中的结点后移语句上。

该语句的执行次数是n-i+1n-i+1n-i+1。

当当i=n+1i=n+1:移动结点次数为:移动结点次数为:移动结点次数为00,即算法在最好时间复杂度是,即算法在最好时间复杂度是0(1) 0(1) 当当i=1i=1:移动结点次数为:移动结点次数为:移动结点次数为n n ,即算法在最坏情况下时间复杂度是,即算法在最坏情况下时间复杂度是0(n) 0(n) ③ 移动结点的平均次数移动结点的平均次数E E is (n)
链表:
1 1:一个单向链表的节点被分成两个部分。

第一个部分保存或者显示关于节点的信息,第二个:一个单向链表的节点被分成两个部分。

第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。

单向链表只可向一个方向遍历。

部分存储下一个节点的地址。

单向链表只可向一个方向遍历。

2:链表最基本的结构是在每个节点保存数据和到下一个节点的地址,在最后一个节点保存一个特殊的结束标记,另外在一个固定的位置保存指向第一个节点的指针,有的时候也会同时储存指向最后一个节点的指针。

一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。

但是也可以提前把一个节点的位置另外保存起来,然后直接访问。

当然如果只是访问数据就没必要了,不如在链表上储存指向实际数据的指针。

这样一般是为了访问链表中的下一个或者前一个(需要储存反向的指针)节点。

下一个或者前一个(需要储存反向的指针)节点。

3:在链表描述中,集合中的元素都放在链表的节点中进行描述。

链表中的节点不是一个数组元素,因此不能通过公式来映射定位某个元素。

取而代之的是,每个节点中都包含了下一个节点的位置信息,链表的表头包含了第一个节点的位置信息。

位置信息,链表的表头包含了第一个节点的位置信息。

4.1 4.1:为了在集合中找到第:为了在集合中找到第k 个元素,就必须从表头开始,遍历第个元素,就必须从表头开始,遍历第11个到第k 个节点。

它的时间复杂度是O(k)O(k),平均时间复杂度为,平均时间复杂度为O(length)O(length)。

4.2 4.2:为了在集合中删除第:为了在集合中删除第k 个元素,就要先找到第k-1k-1和第和第k 个节点,使第k-1k-1个节点的下一个节点的下一个节点位置信息指向第k+1k+1个节点,然后释放第个节点,然后释放第k 个节点所占的空间。

它的时间复杂度是O(k)O(k),平,平均时间复杂度为O(length)O(length)。

4.3 4.3:插入和删除的过程很相似,首先要创建一个新的节点,然后找到第:插入和删除的过程很相似,首先要创建一个新的节点,然后找到第k-1k-1个节点,在该节点个节点,在该节点的后面插入新的节点,并把第k-1k-1个节点、新的节点的下一个节点位置信息进行适当设置。

它的时个节点、新的节点的下一个节点位置信息进行适当设置。

它的时间复杂度是O(k)O(k),平均时间复杂度为,平均时间复杂度为O(length)O(length)。

5 5:采用数组描述方法的集合仅需要能够保存所有元素的空间以及保存集合最大尺寸所需要的:采用数组描述方法的集合仅需要能够保存所有元素的空间以及保存集合最大尺寸所需要的空间。

链表描述需要除集合元素本身的空间意外,还需要额外的空间,用例保存链接节点指向下一个节点位置的指针。

但一般情况下,链表描述要比数值描述的空间利用率高得多。

个节点位置的指针。

但一般情况下,链表描述要比数值描述的空间利用率高得多。

6 6:虽然数组描述、链表描述插入和删除操作的平均时间复杂度均为:虽然数组描述、链表描述插入和删除操作的平均时间复杂度均为O(length)O(length),但由于移动元,但由于移动元素的操作比遍历元素的操作的开销要大得多,所以采用链表描述所实现的插入和删除操作要比数组描述执行得更快。

而采用数组描述可以在常数时间内访问第k 个元素,而在链表中,这种操作所需要的时间是O(k)O(k)。

l 程序流程图程序流程图
顺序表:顺序表: Switch Switch语句,语句,语句,case case case语句;语句;语句; ListInsert_Sq(L, 1, GetCityData());
ListDelete_Name(L, GetName(), citydata);
ListDelete_Coordinate(L, x, y, citydata);
ListSearch_Name(L, GetName(), citydata);
ListSearch_Coordinate(L, X, Y, citydata);
Print(L, GetY(), GetX(), GetDistance());
单链表:单链表:
void CreateList(LinkList &L) void ClearList(LinkList &L) void Destroy(LinkList &L) 
bool GetElem(LinkList &L,int i,CityData &e) int LocateElem(LinkList &L,CityData e, bool (*compare)(CityData, CityData)) bool ListInsert(LinkList &L,int i,CityData e) void ListDelete_Name(LinkList &L,string name,CityData &e) 
void ListTraverse(LinkList L) void ListReadFile(LinkList &L) void Preserve(LinkList L) 
城市数据系统系统城市数据系统系统
插入城市数据
读取已保存记录
打印所有数据
按指定距离打印
按坐标查找城市
按名字查找城市
按坐标删除记录
按名字删除数据
保存数据记录
随机生成数据
城市坐标
城市名称
城市坐标
城市名称
指定距离
城市坐标
城市名称
保存记录
数据长度
打印
读取记录
插入成功
无此记录
查找成功 无此记
录 删除成
功 无此记
录 删除成
功 查找成
功 无此记

输出
3. 源程序清单: 
////顺序表实现城市数据库顺序表实现城市数据库顺序表实现城市数据库 #include <iostream> #include <string> #include "stdlib.h" #include <iomanip> #include <fstream> using namespace std;
#define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define ElemType string
typedef struct { ElemType m_Name; int m_X;
int m_Y;
}CityData;
typedef struct { CityData *elem; int length; ////当前表长当前表长当前表长 int listsize;
//表总长,初始为
100 }SqList;
void InitList_Sq(SqList &L) { L.elem = new CityData[LIST_INIT_SIZE]; if(!L.elem) { exit(0); }
L.length = 0;
L.listsize = LIST_INIT_SIZE;
}
void DestroyList(SqList &L) { L.length = 0; L.listsize = 0; free(L.elem); L.elem = NULL;
}
void ClearList(SqList &L) { L.length = 0; }
bool ListEmpty(SqList L) {
return (L.length == 0)? false : true; }
int ListLength(SqList L) { return L.length;
}
////获取第获取第i 个元素(从1开始计数,下同)开始计数,下同) void GetElem(SqList L, int i, CityData &e) { if(i<1 || i>L.length) { cout<<"cout<<"错误的位置!错误的位置!错误的位置!"<<endl; "<<endl; return ;
} else { e = L.elem[i-1];
}
}
////查找节点查找节点e e 返回位置返回位置返回位置 int LocateElem(SqList
L,
CityData
e,
bool
(*compare)(CityData, CityData))
{ CityData *p; p = L.elem; int i = 0;
while(i<L.length && !(compare(*p, e))) {
p++; i++; }
if(i < L.length) { return i+1; } else { return 0; }
}
////在第在第i 个元素后插入一个元素个元素后插入一个元素
void ListInsert_Sq(SqList &L, int i, CityData e) { if(i>=1 && i<=L.length+1) { ////如果存储空间不足,则以如果存储空间不足,则以LISTINCREMENT 为增量,扩展空间增量,扩展空间
if(L.length >= L.listsize) { CityData *base;
base = new CityData[L.listsize]; for(int count=0; count<L.length; count++)
{
base[count] = L.elem[count]; }
L.elem = new CityData[L.listsize + LISTINCREMENT];
for(int num=0; num<L.length; num++) { L.elem[num] = base[num];
}
delete []base;
L.listsize += LISTINCREMENT;
}
////将第将第i 个元素之后的元素,依次向后移动一位,之后执行插入位,之后执行插入
CityData *q; q = &(L.elem[i-1]); CityData *p;
for(p = &(L.elem[L.length]); p>q; p--) { *p = *(p-1);
} *q =e;
L.length++; cout<<"cout<<"插入成功插入成功插入成功"<<endl; "<<endl;
return;
}
cout<<"cout<<"插入位置非法!插入位置非法!插入位置非法!"<<endl; "<<endl; }
////按名字删除元素,并由按名字删除元素,并由e 返回其值返回其值
void ListDelete_Name(SqList void ListDelete_Name(SqList &L, string &L, string &L, string name, name, name, CityData CityData &e) { if(L.length > 0) { CityData *p = &(L.elem[0]); int count = 0;
while(p->m_Name!=name && count<L.length) { count++; p++;
}
////之后将此元素后的元素依次向前移动一位,之后将此元素后的元素依次向前移动一位,
下同下同 if(count < L.length) { e = *p;
CityData *q = L.elem + L.length -1; for(; p<=q; p++) { *p = *(p+1);
}
L.length--;
cout<<"cout<<"删除成功删除成功删除成功"<<endl; "<<endl;
} else { cout<<"cout<<"数据库中没有该记录数据库中没有该记录数据库中没有该记录"<<endl; "<<endl;
}
}
}
////按坐标删除元素,按坐标删除元素,,并由e 返回其值返回其值
void ListDelete_Coordinate(SqList &L, int X, int Y, CityData &e) { if(L.length > 0) { CityData *p = &(L.elem[0]); int count = 0;
while(p->m_X!=X
&&
p->m_Y!=Y
&&
count<L.length) { count++; p++;
}
if(count < L.length) { e = *p;
CityData *q = L.elem + L.length -1; for(; p<=q; p++) { *p = *(p+1); }
L.length--;
cout<<"cout<<"删除成功删除成功删除成功"<<endl; "<<endl;
} else { cout<<"cout<<"数据库中没有该记录数据库中没有该记录数据库中没有该记录"<<endl; "<<endl; }
}
}
////读取文件中城市信息,更新表(会清除原有表中数据)读取文件中城市信息,更新表(会清除原有表中数据)读取文件中城市信息,更新表(会清除原有表中数据) void ListReadFile(SqList &L) { ClearList(L); CityData citydata; ifstream ifile;
ifile.open("City.txt", ios_base::in); while(ifile>>citydata.m_Name>>citydata.m_X>>ci tydata.m_Y)
{ ListInsert_Sq(L, 1, citydata);
}
ifile.close();
cout<<"cout<<"读取完毕读取完毕读取完毕"<<endl; "<<endl;
}
////按名字检索城市按名字检索城市按名字检索城市
void ListSearch_Name(SqList L, string name, CityData
&e) { if(L.length > 0) { CityData *p = L.elem; int count = 0;
while(p->m_Name!=name && count<L.length)
{
count++; p++;
}
if(count < L.length) { e = *p;
cout<<"cout<<"城市名城市名城市名 : "<<p->m_Name<<endl; : "<<p->m_Name<<endl;
cout<<" cout<<"坐标坐标坐标 X : "<<p->m_X<<endl; X : "<<p->m_X<<endl; cout<<"cout<<"坐标坐标坐标 Y : "<<p->m_Y<<endl; Y : "<<p->m_Y<<endl;
} else
{
cout<<"数据库中没有这个记录
"<<endl; }
}
}
////按坐标检索城市按坐标检索城市按坐标检索城市
void ListSearch_Coordinate(SqList L, int X, int Y, CityData &e) {
if(L.length > 0) { CityData *p = L.elem; int count = 0; while(p->m_X!=X &&
p->m_Y!=Y
&&
count<L.length) { count++; p++;
}
if(count < L.length) { e = *p;
cout<<"cout<<"城市名城市名城市名 : "<<p->m_Name<<endl; : "<<p->m_Name<<endl; cout<<" cout<<"坐标坐标坐标 X : "<<p->m_X<<endl; X : "<<p->m_X<<endl; cout<<"cout<<"坐标坐标坐标 Y : "<<p->m_Y<<endl; Y : "<<p->m_Y<<endl;
} else { cout<<"数据库中没有这个记录
"<<endl;
}
}
}
////打印到指定点距离小于打印到指定点距离小于distance 的城市的城市
void Print(SqList L, int Y, int X, int distance) { if(L.length == 0) { cout<<"cout<<"空,你还没有读取记录,空,你还没有读取记录,空,你还没有读取记录,或者记录为空或者记录为空"<<endl;
return; }
for(int i=0; i<L.length; i++)
{ int x = (L.elem[i].m_X>=X)? L.elem[i].m_X-X : X-L.elem[i].m_X; int
y
=
(L.elem[i].m_Y>=Y)?
L.elem[i].m_Y-Y : Y-L.elem[i].m_Y;
int Distance = x*x+y*y; int d = distance*distance; if(Distance<=d) {
cout<<"
城市名 : "<<L.elem[i].m_Name<<endl;
cout<<"


X
:
"<<L.elem[i].m_X<<endl; cout<<"cout<<"坐标坐标坐标 Y : "<<L.elem[i].m_Y<<endl; Y : "<<L.elem[i].m_Y<<endl; } i++;
}
}
////将表中城市信息保存到文件中(会清除文件中原有数据)将表中城市信息保存到文件中(会清除文件中原有数据)将表中城市信息保存到文件中(会清除文件中原有数据) void Preserve(SqList L) {
ofstream ofile;
ofile.open("City.txt", ios_base::out); for(int i=0; i<L.length; i++) { ofile<<L.elem[i].m_Name<<"
"<<L.elem[i].m_X<<" "<<L.elem[i].m_Y<<endl;
}
ofile.close();
cout<<"cout<<"存档成功存档成功存档成功!"<<endl; !"<<endl;
}
////打印出所有节点打印出所有节点打印出所有节点
void ListTraverse(SqList L) { if(L.length == 0) { cout<<"cout<<"空,空,空,你还没有读取记录,或者记录为空你还没有读取记录,或者记录为空
"<<endl;
}
else {
for(int i=0; i<L.length; i++)
{
4.运行结果: 
对于需要比较不同算法性能优劣的题目,应设计并填写一张性能比较表格,列出不同算法在同一指标下的性能表现。

但仅仅罗列出一堆数据是不够的,还应将数字转化为图象、曲线等,帮助读者更直观地理解测试结果。

者更直观地理解测试结果。

对于需要利用某算法解决某问题的题目,应设计并填写一张测试用例表。

每个测试用例至少应包括下列内容:
包括下列内容:
l测试输入:设计一组输入数据;
测试输入:设计一组输入数据;
l测试目的:设计该输入的目的在于测试程序在哪方面可能存在的漏洞;
测试目的:设计该输入的目的在于测试程序在哪方面可能存在的漏洞;
l正确输出:对应该输入,若程序正确,应该输出的内容;
正确输出:对应该输入,若程序正确,应该输出的内容;
l实际输出:该数据输入后,实际测试得到的输出内容;
实际输出:该数据输入后,实际测试得到的输出内容;
l错误原因:如果实际输出与正确输出不符,需分析产生错误的可能原因;
错误原因:如果实际输出与正确输出不符,需分析产生错误的可能原因;
l当前状态:分为“通过”(实际输出与正确输出相符)、“已改正”(实际输出与正确输出不符,但现在已修改正确)、“待修改”(实际输出与正确输出不符,且尚未改正)三种状态。

(举例):
序号功能
名称
测试项
描述
描述//输入
输入//操

期望结果真实结果备注
1 插入
一个
城市
的数
据能否插入并保
存一个城市的
数据
输入1,根据提
示输入一个城
市的名称,
市的名称,x x坐
标,
标,y y坐标,如
重庆,
重庆,11,1
能够输入
一个城市
的名称,
的名称,x x
坐标,y坐
标并保存
城市名称和
x,y坐标能
输入并能够
保存
通过
2 按名
字删
除城
市的
数据按照城市的名
字删除城市的
所有数据
输入2,根据提
示输入城市名
称,如重庆
删除这个
城市名称
的所有数
据,同时会
计算出算
法的时间
删除了这个
城市名称的
所有数据,
计算出了算
法的时间
通过
3 按坐
标删
除城
市的
数据按照城市的坐
标删除该城市
的所有数据
输入3,根据提
示输入城市的
x,y坐标,如
1,1
删除了该
x,y坐标
的城市的
所有数据,
计算出算
法的时间
删除了该x,
y坐标的城
市的所有数
据,计算出
了算法的时

通过
4 按名
字查
找城
市的
数据按城市名称查
找一个城市,并
显示该城市的
相关信息
输入4,根据提
示输入城市名
称,如重庆
显示关于
这个城市
的相关信
息,计算出
算法的时

显示了关于
这个城市的
相关信息,
计算出了算
法的时间
通过
5 按坐
标查
找城
市的
数据按城市坐标查
找一个城市,并
显示该城市的
相关信息
输入5,根据提
示输入城市坐
标,如输入1,1
显示关于
这个城市
的相关信
息,计算出
算法的时

显示了关于
这个城市的
相关信息,
计算出了算
法的时间
通过
6 按指
定点
距离
内显
示记按照规定的距
离内显示该距
离内的数据
输入6,根据提
示输入距离5
显示该距
离内的数

显示了该距
离内的数据
通过

7
显示所有城市的数据 显示当前所有城市的数据
输入7
显示当前所有城市的数据 显示了当前所有城市的数据
通过 8
读取已保存的城市的数据 读取已经存档的所有城市的数据,即刷新表中的数据
输入8
读取了存档的所有数据
读取了存档的所有数据
通过 9
保存
存储数据 输入9
存储所有所有数据 存储了所有数据
通过 0
随机生成 随机生成城市名称和坐标
先输入0,再根据要求输入产生的长度 会随机生成相应长度的数据
输入7,会显示出随机产生的相应长度的数据
通过 测试结论
各项功能已经基本实现,但其中有些部分太过繁杂,可以简化一些,尤其是进行下一项操作时,前面的操作会消失,这会带来许多不便,需要改进
备注:分为“通过”(实际输出与正确输出相符)、“已改正”(实际输出与正确输出不符,但现在已修改正确)、“待修改”(实际输出与正确输出不符,且尚未改正)三种状态。

可在此说明错误原因(实际输出与正确输出不符,且尚未改正)三种状态。

可在此说明错误原因
这一部分需根据题目类型设计提供相应的测试方法和结果(这一部分需根据题目类型设计提供相应的测试方法和结果(请勿粘贴测试结果图请勿粘贴测试结果图)。

5. 实验运行情况分析(包括算法、运行结果、运行环境等问题的总体讨论)。

算法分析比较:顺序表和链表的使用各有优劣。

顺序表和链表的使用各有优劣。

顺序表需要提前估计线性表的大小并且插入删除效率低需要移动大量结点,优点在
于表中节点没有浪费存储空间,并且可以按位置随机访问,存储速度快;
链表优点在于插入删除效率高,无需提前估计表的大小(大小无需固定),表中元素个数没有限制,缺点在于访问结点需要从表头遍历查找并且每个节点除了储存元素还需要附加空间存储指针。

需要附加空间存储指针。

顺序表和链表时间性能比较:像取出线性表中第顺序表和链表时间性能比较:像取出线性表中第顺序表和链表时间性能比较:像取出线性表中第 i 个元素这样的按位置随机访问的操作,使用顺序表更快一些;取前趋和后继结点的操作在顺序表中可以很容易调整当前的位置向前或向后,因此这两种操作的时间为 O (1) ;
相比之下,相比之下,单链表不能直接访问上述的元素,单链表不能直接访问上述的元素,单链表不能直接访问上述的元素,按位置访问只能从表头开始,按位置访问只能从表头开始,按位置访问只能从表头开始,直到找直到找到那个特定的位置,所需要的平均时间为 O ( n ) 。

给出指向链表中某个合适位置的指针后,指针后,插入和删除操作所需的时间仅为插入和删除操作所需的时间仅为插入和删除操作所需的时间仅为 O ( 1 )
,而顺序表进行插入和删除操作需。

相关文档
最新文档