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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2、软件环境:Windows 8下的Microsoft Visual Studio 2008
2.算法描述:
数据结构与算法分析的背景:
数据结构是计算机程序设计的重要理论技术基础,它不仅是计算机学科的核心课称,而且已成为其他理工专业的热门选修课。
数据结构是一门专业选技术基础科。一方面,它要求我们学会分析研究计算机加工的数据结构的特性,以便为应用涉及的数据选择适当的逻辑结构、存储结构及其相应的算法,并初步掌握算法的时间分析和空间分析的技术;另一方面,数据结构的学习过程也是复杂程序设计的训练过程,要求我们编写的程序结构清楚和正确易读,复合软件工程的规范,并培养我们的数据抽象能力。本次课程设计就是对数据结构中的顺序表和链表的操作的应用。
for(; p<=q; p++)
{
*p = *(p+1);
}
L.length--;
cout<<"删除成功"<<endl;
}
else
{
cout<<"数据库中没有该记录"<<endl;
}
}
}
//按坐标删除元素,,并由e返回其值
void ListDelete_Coordinate(SqList &L, int X, int Y, CityData &e)
LOC(ai)= LOC(a1)+(i-1)*c 1≤i≤n
注意:
在顺序表中,每个结点ai的存储地址是该结点在表中的位置i的线性函数。只要知道基地址和每个结点的大小,就可在相同时间内求出任一结点的存储地址。是一种随机存取结构。
顺序表上实现的基本运算:
表的初始化;求表长;取表中第i个结点;查找值为x的结点;插入
程序流程图
3.源程序清单:
//顺序表实现城市数据库
#include <iostream>
#include <string>
#include "stdlib.h"
#include <iomanip>
#include <fstream>
using namespace std;
#define LIST_INIT_SIZE 1wenku.baidu.com0
4.2:为了在集合中删除第k个元素,就要先找到第k-1和第k个节点,使第k-1个节点的下一个节点位置信息指向第k+1个节点,然后释放第k个节点所占的空间。它的时间复杂度是O(k),平均时间复杂度为O(length)。
4.3:插入和删除的过程很相似,首先要创建一个新的节点,然后找到第k-1个节点,在该节点的后面插入新的节点,并把第k-1个节点、新的节点的下一个节点位置信息进行适当设置。它的时间复杂度是O(k),平均时间复杂度为O(length)。
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)
{
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;
{
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++)
}
*q =e;
L.length++;
cout<<"插入成功"<<endl;
return;
}
cout<<"插入位置非法!"<<endl;
}
//按名字删除元素,并由e返回其值
void ListDelete_Name(SqList &L, string name, CityData &e)
{
if(L.length > 0)
顺序表:
1.顺序表的定义
(1) 顺序存储方法
即把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法。
(2) 顺序表(Sequential List)
用顺序存储方法存储的线性表简称为顺序表(Sequential List)。
2. 结点ai的存储地址
不失一般性,设线性表中所有结点的类型相同,则每个结点所占用存储空间大小亦相同。假设表中每个结点占用c个存储单元,其中第一个单元的存储地址则是该结点的存储地址,并设表中开始结点a1的存储地址(简称为基地址)是LOC(a1),那么结点ai的存储地址LOC(ai)可通过下式计算:
5:采用数组描述方法的集合仅需要能够保存所有元素的空间以及保存集合最大尺寸所需要的空间。链表描述需要除集合元素本身的空间意外,还需要额外的空间,用例保存链接节点指向下一个节点位置的指针。但一般情况下,链表描述要比数值描述的空间利用率高得多。
6:虽然数组描述、链表描述插入和删除操作的平均时间复杂度均为O(length),但由于移动元素的操作比遍历元素的操作的开销要大得多,所以采用链表描述所实现的插入和删除操作要比数组描述执行得更快。而采用数组描述可以在常数时间内访问第k个元素,而在链表中,这种操作所需要的时间是O(k)。
(4)算法分析
① 问题的规模
表的长度L->length(设值为n)是问题的规模。
② 移动结点的次数由表长n和插入位置i决定
算法的时间主要花费在for循环中的结点后移语句上。该语句的执行次数是n-i+1。
当i=n+1:移动结点次数为0,即算法在最好时间复杂度是0(1)
当i=1:移动结点次数为n,即算法在最坏情况下时间复杂度是0(n)
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);
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;
{
cout<<"错误的位置!"<<endl;
return ;
}
else
{
e = L.elem[i-1];
}
}
//查找节点e 返回位置
int LocateElem(SqList L, CityData e, bool (*compare)(CityData, CityData))
{
CityData *p;
#define LISTINCREMENT 10
#define ElemType string
typedef struct
{
ElemType m_Name;
int m_X;
int m_Y;
}CityData;
typedef struct
{
CityData *elem;
int length;//当前表长
② 当插入位置i的值为i>n或i<1时为非法位置,不可做正常插入操作;
(2) 顺序表插入操作过程
在顺序表中,结点的物理顺序必须和结点的逻辑顺序保持一致,因此必须将表中位置为n ,n-1,…,i上的结点,依次后移到位置n+1,n,…,i+1上,空出第i个位置,然后在该位置上插入新结点x。仅当插入位置i=n+1时,才无须移动结点,直接将x插入表的末尾。
for(; p<=q; p++)
{
*p = *(p+1);
}
L.length--;
cout<<"删除成功"<<endl;
}
else
{
cout<<"数据库中没有该记录"<<endl;
3:在链表描述中,集合中的元素都放在链表的节点中进行描述。链表中的节点不是一个数组元素,因此不能通过公式来映射定位某个元素。取而代之的是,每个节点中都包含了下一个节点的位置信息,链表的表头包含了第一个节点的位置信息。
4.1:为了在集合中找到第k个元素,就必须从表头开始,遍历第1个到第k个节点。它的时间复杂度是O(k),平均时间复杂度为O(length)。
{
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;
}
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)
{
{
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;
链表顺序表实验报告--数据结构与算法分析
数据结构与算法分析课程设计报告
课题名称:使用一个链表和顺序表构建城市数据库
提交文档组号:2
编程学生姓名及学号:
测试学生姓名及学号:
报告学生姓名及学号:
指导 教 师 姓 名:
指导教师评阅成绩:
指导教师评阅意见:
.
.
提交报告时间: 2013 年 11 月 日
实验一:Implement a city database using unordered listsand link lists
(1) 插入运算的逻辑描述
线性表的插入运算是指在表的第i(1≤i≤n+1)个位置上,插入一个新结点x,使长度为n的线性表:
(a1,…,ai-1,ai,…an)
变成长度为n+1的线性表:(a1,…,ai-1,x,ai,…an)
注意:
① 由于向量空间大小在声明时确定,当L->length≥List Size时,表空间已满,不可再做插入操作;
③ 移动结点的平均次数Eis(n)
链表:
1:一个单向链表的节点被分成两个部分。第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。单向链表只可向一个方向遍历。
2:链表最基本的结构是在每个节点保存数据和到下一个节点的地址,在最后一个节点保存一个特殊的结束标记,另外在一个固定的位置保存指向第一个节点的指针,有的时候也会同时储存指向最后一个节点的指针。一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。但是也可以提前把一个节点的位置另外保存起来,然后直接访问。当然如果只是访问数据就没必要了,不如在链表上储存指向实际数据的指针。这样一般是为了访问链表中的下一个或者前一个(需要储存反向的指针)节点。
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)
1.实验的目的和要求:
<1>采用C++的ASCII码文件和模块函数实现;
<2>熟练掌握数组列表和链表列表的实现;
<3>熟练掌握计算机系统的基本操作方法,了解如何编译、运行一个C++程序;
<4>上机调试程序,掌握查错、排错使程序能正确运行。
2.实验的环境:
1、硬件环境:索尼笔记本电脑,Intel(R) Core(TM) i7-3632M,8GB内存可;
相关文档
最新文档