数据结构导论 三 线性表-顺序存储

线性表是什么样子呢?

 类似这种,可以当作生活中流水线作业是一样的。

线性表是由n(N>=0)个数据元素(结点)比如a1,a2,a3....an组成的有限序列

数据元素的个数n定义为表的长度,

当n=0时为空表(null) 

当n>0时为非空表 L=(a1....an)

a1称为起始点 ,an为终端结点。

对任意一堆相邻结点ai和ai+1 (1<i<n)  ai是ai+1的直接前驱,ai+1是ai的直接后继

 (图片来源于网络)

如果吧线性表当作火车就更加明显了,火车只有一个火车头(起始节点)一个车尾(终端结点)

火车头(起始节点)前面没有车厢(直接前驱) 但是后面又一节车厢 (直接后继),车尾(终端结点)后面没有多余的车尾(直接后继) ,但是车尾的前面有一节车厢(直接前驱)。

综上可以了解出每一个结点且都有一个直接前驱和一个直接后继

线性表的逻辑结构特征

对于非空的线性表:线性表中结点具有一对一的关系(具体可以看上面的火车例子)

1)线性表中有且仅有一个其实结点a1,没有直接前驱,有且仅有一个直接后继a2;

2)有且仅有一个终端结点an,没有直接后继,有些仅有一个直接前驱an-1;

3)其余的内部结点ai(a<=i<=n-1)都有且仅有一个直接前驱ai-1和一个直接后继ai+1;

线性表的基本运算

初始化 Initiate  秋表长度Length 取表元 get  定位 Locate 插入Insert 删除Delete

线性表顺序存储的方法是:将表中的结点依次存放在计算机内存一组连续的存储单元中,数据元素在线性表中的邻接关系决定它们在存储空间中的存储位置,即逻辑结构中相邻的结点其存储位置也相邻。

用顺序存储实现的线性表称为顺序表。一般使用数组来表示顺序表。 

假定有一组数据,数据间有顺序:13 4 5 15 9 53 24 50 88 42 11

此处数据间的顺序即表示数据间的逻辑关系即线性关系,这一组数据为线性表:

 假设已知a1地址为loc(a1),每个数据占c个单元,则计算ai地址

Loc(ai)=Loc(a1)+c*(i-1)

比如 a3 的地址

1 a1=0 
2 
3 Loc(a3)=a1+(3-1)
4 
5             =0+2
6 
7             =2

初始化

strudt student{
int ID;//ID
char name[30];//姓名
char sex; //性别
int class;//班级
int age;//年龄

}
student={"01",“zhangsan”,"m","201","20"};

  插入

线性表的插入运算是指在表的第i(1<=i<=n+1)个位置上,插入一个新结点x,使长度为n的线性表“:(a1,....ai-1,ai,ai+1,....an)

变成长度为n+1的线性表:

(a1,...ai-1,x,ai,ai+1,....an)

1)当表空间已满,不可在做插入操作

2)当插入位置为非法位置,不可做正常插入操作

void  InsertSeqlist (SeqList l,dataType x,int i){
if (l.length==Maxsize)exit("表已满");
if(i<1||l.length+1) exit (”位置错误“);//插入位置是否正确
for(j=l.length;j>=i;j--){//初始化i=l.length
l.data[j]=l.data[j-1];//依次后移
l.data[i-1]=x;//元素x置入到下标为i-1的位置
l.length++;}//表长度加1

假设线性表中含有n个数据元素,
在进行插入操作时,有 n+1个位置可插入
在每个位置插入数据的概率是:1/(n+1)
在i位置插入时,要移动n-i+1 个数据

平均时间复杂度为O(n)

删除

线性表的删除运算是指将表的i的结点删去,使长度为n的线性表长度”减一“

当要删除元素的位置I不在表长范围内(即i<1或i->length)时,为非法位置,不能做正常的删除操作

操作过程:

1,若i=n,则只要删除终端结点,无需移动结点;

2,若1<=i<=n-1,则必须将表中位置i+1,i+2,,,,,n的结点,依次前移到位置I

3,该表长度减1

void DeleteSeqList(SeqList L,int i) {
//删除线性表L中的第i个数据结点
if(i<1 || i>L.length) //检查位置是否合法
exit(“非法位置”);
for(j=i;j<L.length;j ++) //第i个元素的下标为i-1
L.data[j-1]=L.data[j]; //依次左移
L.length--; //表长度减1
}

 删除算法的分析

 

假设线性表中含有n个数据元素,
在进行删除操作时,有 n位置可删除
在每个位置删除数据的概率是:1/n
在i位置删除时,要移动 n-i+1个数据
假定在n个位置上删除元素的可能性均等,

平均时间复杂度为O(n)顺序存储结构表示的线性表,在做插入或删除操作时,平均需要移动大约一半的数据元素。

当线性表的数据元素量较大,并且经常要对其做插入或删除操作时,这一点需要值得考虑 

定位(查找)

定位运算LocateSeqlist(L,X)的功能是
求L中值等于X的结点序号的最小值,

当不存在这种结点时结果为0 从第一个元素 a1 起依次和x比较,直到找到一个与x相等的数据元素,则返回它在顺序表中的存储下标或序号;或者查遍整个表都没有找到与 x 相等的元素,返回0 

int LocateSeqlist(SeqList L, DataType x)
{
int i=0;
while ((i<L. length) && (L.data[i]!=x) ) //在顺序表中查找值为 x 的结点
i++;
if(i<L.length) return i+1; //若找到值为x的元素,返回元素的序号
else return 0; //未查找到值为x的元素,返回0
}
//顺序表的求表长操作,直接输出L.length即可

  1)设表的长度length=n,在插入算法中,元素的移动次数不仅与顺序表的长度
n有关, 还与插入的位置i有关。 插入算法在最坏情况下,其时间复杂度为O(n)
一般情况下元素比较和移动的次数为n-i+1次,插入算法的平均移动次数约为n/2
其时间复杂度是O(n)
2)删除算法DeleteSeqlist,可得其在最坏情况下元素移动次数为n-1,时间复杂
度为O(n),元素平均移动次数约为(n-1/2,时间复杂度为O(n)
3)对于定位算法,需要扫描顺序表中的元素。以参数x与表中结点值的比较为
标准操作,平均时间复杂度为O(n)。求表长和读表元素算法的时间复杂度为O(1)
就阶数而言,己达到最低

顺序表的优点:

无需为表示结点间的逻辑关系而增加额外存储空间
可以方便地随机存取表中的任一结点

顺序表的缺点:

插入和删除运算不方便,必须移动大量的结点
顺序表要求占用连续的空间,存储分配只能预先进
行,因此当表长变化较大时,难以确定合适的存储
规模

原文地址:https://www.cnblogs.com/X404/p/12013976.html