线性表3
让编程改变世界
Change the world by program
线性表的顺序存储结构
我们可以想象,线性表有两种物理存储结构:顺序存储结构和链式存储结构。
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
线性表(a1,a2,…,an)的顺序存储如下:
上边的图片大家想到了什么?
是不是跟丫的数组一样一样的?!
物理上的存储方式事实上就是在内存中找个初始地址,然后通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次放在这块空地中。
大家可能喜欢听小甲鱼拿现实的栗子来举例。
哈,就例如小甲鱼带着咱的鱼C旅游团去看电影,看那个叫3D*蒲团有木有?!
哎哟,去到电影院人山人海,但妹子的身影还是难以逃过小甲鱼的火眼精金,所以小甲鱼猛地带领众鱼油一把夺下了妹子旁边的一排位置。。。。。。
话说小甲鱼拿下第一个位置后,鱼油们果断依次坐下,这样子我们就建立了一个线性表。
由此可见,这小甲鱼夺下的第一个位置是非常关键的,如果妹子身旁的位置被其他人占据了,小甲鱼就不能代替大家问到妹子的联系方式了!
可现实中总会有些不按部就班来的,例如黑夜喜欢乱吃零食,所以他又拉肚子了。。。
但是黑夜买票了,所以他的位置就算空着,也没有人会坐上去。这就是顺序存储结构的特性之一。
接下来看线性表顺序存储的结构代码:
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int length; // 线性表当前长度
} SqList;
大家看到了,这里我们封装了一个结构,事实上就是对数组进行封装,增加了个当前长度的变量罢了。
总结下,顺序存储结构封装需要三个属性:
存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置。
线性表的最大存储容量:数组的长度MaxSize。
线性表的当前长度:length。
注意,数组的长度与线性表的当前长度需要区分一下:
数组的长度是存放线性表的存储空间的总长度,一般初始化后不变。
而线性表的当前长度是线性表中元素的个数,是会变化的。
地址计算方法
我们或许习惯了数组的从0开始的计算方法,所以导致小甲鱼像去电影院坐错位置被妹子怒骂无耻等尴尬事件不胜枚举。
线性表的定义充分考虑到很多军师级别领导的智商指数,所以决定从1开始回归正常思维。
假设ElemType占用的是c个存储单元(字节),那么线性表中第i+1个数据元素和第i个数据元素的存储位置的关系是(LOC表示获得存储位置的函数):LOC(ai+1) = LOC(ai) + c
所以对于第i个数据元素ai的存储位置可以由a1推算得出:LOC(ai) = LOC(a1) + (i-1)*c
结合下图来理解:
通过这个公式,我们可以随时计算出线性表中任意位置的地址,不管它是第一个还是最后一个,都是相同的时间。
那么它的存储时间性能当然就为O(1),我们通常称为随机存储结构<----顺序存储结构的线性表。
获得元素操作
实现GetElem的具体操作,即将线性表L中的第i个位置元素值返回。
就程序而言非常简单了,因为线性表是从1开始,数组下标是从0开始的,所以我们只需要把数组第i-1下标的值返回即可。
插入操作
刚才我们也谈到,线性表的顺序存储结构具有随机存储结构的特点,时间复杂度为O(1)。
大家现在来考虑下,如果我们要实现ListInsert(*L, i, e),即在线性表L中的第i个位置插入新元素e,代码应该如何写?
例子接着举,刚才小甲鱼在电影院成功的博得妹子的欢心,妹子表示愿意加入我们鱼C旅游团。
大家狠兴奋丫有木有!因为大家都希望小甲鱼把妹子排到自己身边。
但是我们要按我们定下的规则来排:按身高顺序。
所以插入算法的思路:
<span style="font-size:24px;color:#ff0000;background-color: rgb(255, 153, 0);"><strong>如果插入位置不合理,抛出异常;
如果线性表长度大于等于数组长度,则抛出异常或动态增加数组容量;
从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
将要插入元素填入位置i处;
线性表长+1。</strong></span>
转自:http://blog.fishc.com/1701.html