数据结构与算法--线性表系列(顺序存储结构的线性表)

  hello,everybody!又与大家见面了,因为线性表这章内容比较多一些,还有一些代码需要practice,所有好多天没有写博客。今天让我们一起来学习数据结构---线性表吧。

线性表的定义:

顾名思义,线性表,就是具有线性质的一种数据结构。书中的例子是这样说的:本书作者去幼儿园接孩子,发现了一个very interesting 的现象。孩子们每次都是排着队放学,每个孩子前面有个唯一的小朋友,后面也有一个唯一的小朋友。他们之间的关系是一对一的关系。好像是一条线把他们栓在了一起似的,这个例子很形象的向线性表做了诠释。

线性表(List):零个或多个数据元素的有限序列。

首先,数据元素要有限,不能是无限多个数据元素。其次,他们之间是有秩序的,是按顺序来存储https://signup.wordpress.com/activate/9e822d27ba11e157 的。就像,幼儿园的小朋友排队似的,是按顺序来。

线性表是数据结构中,用的最多的,也是最简单的一种数据结构。学好线性表很重要,她重要,必须学好。她简单,更要学好,把简单的学好了,我们才有信心学习之后较复杂的数据结构。

 

线性表的抽象数据类型:

通过前面的线性表的定义,我们知道了,线性表结构是相同数据元素之间的有限序列。所以,我们可以用数组来表示线性表。创建固定大小的数组,就相当于在内存中找个了一段地址连续的存储空间,我们可以把线性表存入到数组中。们把线性表的元素个数,称为线性表的长度。这里我们要区分两个概念线性表长度””数组长度”

线性表的长度:是指表中所存元素的多少,她会随着元素的改变而改变。

数组的长度:它是来存放线性表的,相当于在内存总的开辟的空间。它一般是不会改变的。

一般情况下,线性表的大小小于等于数组的大小。

现在我们来看一下线性表的抽象数据类型:

image

image

我们来分析一下,线性表都会有哪些操作?

Firstly,创建线性表。InitList(*L)

Secondly,判断线性表是否为空.ListEmpty(L)

Thirdly,清空线性表。ClearList(*L)

Fourthly,读取线性表中某个位置的元素。GetElem(L,I,*e)

Fifthly,匹配元素。LocateList(L,e)

sixthly,插入元素。ListInsert(*L,I,e)

seventhly,删除元素。ListDelete(*L,I,*e)

eighthly,计算线性表的长度.

以上是些基本的线性表操作,对于一些复杂的操作,我们可以组合这些基础操作来完成。例如,两个线性表的并集操作。

 

线性表的存储结构

在第一章,讲解数据结构的概叙时,我们提到了,数据结构分为逻辑结构,物理结构。逻辑结构,是描述数据之间的存在关系。物理结构又称为存储结构,是将逻辑关系在内存中表现出来。存储结构分为两种,一种为顺序存储,一种为线性存储。

我们先来学习一下线性表的顺序存储。

线性表的顺序存储结构:指的是用一组地址连续的存储单元依次存储线性表的数据元素。

image

线性表的顺序存储的结构代码:

image

 

这里,我们发现描述线性表的顺序存储的结构需要三个属性:

Firstly,存储空间的起始位置:数组data,它的起始位置就是存储空间的起始位置。

Secondly,线性表的最大存储容量:数组的长度。

Thirdly,线性表的当前长度:length.

 

线性表顺序存储结构的操作

获得元素操作:

获得元素的算法思路:

Firstly:线性表L必须存在,不为空.

Secondly:位置i必须在线性表的合理位置。

#define ok 1
#define Error 0
#define TRUE 1
#define False 0
typedef int Status; /*Status是函数的类型,其值是函数结果状态码,如OK等*/

/*初始条件:顺序线性表L已存在,1《=i《=ListLength(L)*/
/*操作结果:用e返回L中第i个数据元素的值*/
Status GetElem(SqlList L,int I,ElemType *e)

{

       if(i<1||i>L.length||L.length==0)

return Error;

else

*e=L.data[i-1];

return Ok;

}

线性表的插入操作:

插入的算法思路:

Firstly,插入位置i要合理,否则抛出异常。

Secondly,线性表的长度大于或等于数组长度,抛出异常或动态增加容量。

Thirdly,从表中最后一位开始,一直遍历到位置i.依次向后移动一个位置。

Fourthly, 将要插入的元素插入i位置。

Fifthly,线性表的长度增加1.

Status ListInsert(SqlList *L,int I,EnlemType e)

{

    int k;

   if(L->length==MAXSIZE)/*线性表的容量等于数组容量,线性表已满*/

return ERROR;

if(i<1||i>L->length+1)/*i位置不合理*/

return ERROR;

if(i<=L->length)/*判断不是向表尾插入数据*/

{

            for(k=L->length-1;k>=i-1;k—)

            L->data[k+1]=L->data[k];   /*将要插入位置元素以及之后的所有元素向后移动一位*/

}

       L->data[i-1]=*e; /*将要插入的数据插入i位置*/

L->length++;/*线性表的长度加1*/

return OK;

}

 

线性表的删除操作:
删除操作的算法思路:

Firstly,删除位置i合理,否则抛出异常。

Secondly,将i位置的元素赋值给e。

Thirdly,,从i位置开始,直到最后一位元素,依次向前移动一个位置。

Fourthly,线性表的长度减1.

Status ListDelete(SqlList *L,int I,EnlemType *e)

{

int k;

if(L->length==0)/*线性表为空*/

return ERROR;

*e=L->data[i-1];

if(i<1||i>L.length)

return ERROR;

if(i<L.length)

{

for(k=1;k<length;k++)

  L->data[k-1]=L->data[k];

}

L->length—;

return OK;

}

 

我们仔细观察,发现了如果是存取数据,线性表的顺序存储结构的时间复杂度为O【1】.如果是插入、删除,时间复杂度为O【n】.那么我们就得出了一个结论,对于线性表中元素移动变化不大,更多的是存储数据的应用,那么我们顺序存储结构是不错的选择。

线性表顺序存储结构的优缺点

优点:

Firstly,可以快速存取线性表中任一位置的元素。

Secondly,无需为了表示表中的数据之间的逻辑关系而增加额外的存储空间

缺点:

Firstly,插入、删除元素会影响其他元素,需要移动大量的数据。

Secondly,当线性表的容量变化较大时,难以确定存储空间的容量。

Thirdly,造成存储空间的“碎片”。

因为线性表内容比较多,我会分多篇文章介绍。

posted @ 2014-06-02 20:16  VitoCorleone  阅读(697)  评论(0编辑  收藏  举报