3.5 顺序存储结构的插入和删除
3.5.1 获得元素操作
对于线性表的顺序存储结构来说,如果要实现GetElem操作 【 即将线性表L中的第i个位置元素值返回】
其实是非常简答的。就程序而言,只要i的数值在数组下标范围内,就是把数组第i-1个下标的值返回即可。来看代码:
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; /*Status是函数类型(注意,Status:是整型),其值是函数结果状态代码,如OK等*/
/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作结果:用e返回L中第i个数据元素的值*/
Status GetElem(SqList L,int i, ElemType *e)
{
if(L.length==0 || i<1 || L.length)
{
return ERROR;
}
*e = L.data [ i-1 ];
return OK;
}
3.5.2 插入操作
我们要实现Listsert (*L,i,e) 【即:在线性表L中的第i个位置插入新元素e,应该如何操作?】
精辟大话:举例,我们春运是买火车票,大家都排队好好的,这时来个美女,对着队伍中排在第三位的你说:“大哥,求求你,帮帮忙,我家有急事,要回去,这么长的队,你能否让我排在你前面?”,你心一软,让她插了队。你必须退后一步,腾出一地方给她,你后面排队的人也得一个一个的全部得退后一步,骂声四起.....
这个例子已经说明了线性表顺序存储结构,在插入数据时的实现过程:
插入的算法思路:
& 如果插入的位置不合理,抛出异常;
& 如果线性表长度等于数组长度,则抛出异常或动态增加容量;
&从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
&将要插入的元素填进位置i处
&表长加1;
实现代码如下:
/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作结果:在L中第i个数据元素的值之前插入新的数据元素e,L的长度加1*/
Status ListInsert (SqList *L, int i, ElemType e)
{
int k;
if (L->length==MAXSIZE) //线性表长度>数组长度 的错误情况
return ERROR;
if (i<1 || i>L->length+1 ) //插入位置不合法 的错误情况
return ERROR;
if (i<=L->length) //正常情况
{
for (k=L->length-1;k>=i-1;k--) //从链表尾开始一个个往后挪一个位置,直至到i位置
{
L->data[k+1] = L->data[k]; //数据域一个个往后挪
}
L->data[i-1] =e; //找到i-1位置后,把e元素放其中
L->length++; //线性链表总长度加1
return OK;
}
}
3.5.3 删除操作
精辟大话之--美女插队 后续故事:此时后面的排队人群意见都很大,突然远处跑来一人,对着美女喊:“你这骗子,终于找到你了,快还我钱!”,这女子二话不说,冲出队伍,胖子紧追其后,消失在人群中....原来那骗子是倒卖车票的黄牛党。空出来的这个位置,于是排队的人群又一个个的往前挪定,骂声渐息....
这就是线性表顺序存储结构的删除元素的过程:
删除算法的思路:
& 如果删除位置不合理,抛出异常;
&取出删除元素;
&从删除元素的位置开始遍历到最后一个元素的位置,分别将它们都向前移动一个位置;
&表长减1;
实现代码如下:
/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作结果:删除L中第i个数据元素并用e返回其值,L的长度减1*/
Status ListDelete (SqList *L, int i, ElemType e)
{
int k;
if (L->length==0) //线性表长度为空
return ERROR;
if (i<1 || i>L->length) //删除位置不合法 的错误情况
return ERROR;
if (i<L->length) //如果删除不是最后位置
{
for (k=i;k<L->length;k++) //从链表尾开始一个个往后挪一个位置,直至到i位置
{
L->data[k-1] = L->data[k]; //数据域一个个往后挪
}
L->length--; //线性链表总长度减1
return OK;
}
}
现在我们来分析一下,删除和插入的时间复杂度:
先来看最好的情况,如果元素要插到最后一个位置,或者删除最后一个元素,此时时间复杂度为O(1),因为不需要移动元素的,就如同一个新人要来排队,那当然排在最后,如果他不想排,那么他一个人离开就好了,不影响其他任何人。
最坏的情况是,如果元素要插入到第一个或者删除第一个元素,此时时间复杂度是多少?那就意味着要移动所有的元素向后或者向前,所以这个时间复杂度为O(n).
3.5.4 线性表顺序存储结构的优缺点
优点 | 缺点 |
无需为表示表中元素之间的逻辑关系而增加额外的存储空间 | 插入和删除操作需要移动大量的元素 |
可以快速的存取表中任一位置的元素 | &当线性空间变化较大时,很难确定存储空间的容量 &造成存储空间的“碎片” |