刚才我们也谈到,这里的时间复杂度为O(1)。我们现在来考虑,如果我们要实现ListIn-sert(*L,i,e),即在线性表L中的第i个位置插入新元素e,应该如何操作?
举个例子,本来我们在春运时去买火车票,大家都排队排的好好的。这时来了一个美女,对着队伍中排在第三位的你说,“大哥,求求你帮帮忙,我家母亲有病,我得急着回去看她,这队伍这么长,你可否让我排在你的前面?”你心一软,就同意了。这时,你必须得退后一步,否则她是没法进到队伍来的。这可不得了,后面的人像蠕虫一样,全部都得退一步。骂声四起。但后面的人也不清楚这加塞是怎么回事,没什么办法。
这个例子其实已经说明了线性表的顺序存储结构,在插入数据时的实现过程
(如图所示)。
插入算法的思路:
- 如果插入位置不合理,抛出异常;
- 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
- 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
- 将要插入元素填入位置i处; ?表长加1。
实现代码如下:
//2.动态顺序表实践,2.4指定位置插入数据https://www.yuque.com/muzichenqing/wpdm33/qrkb1f
/* 初始条件:顺序线性表L已存在,1 ≤ i ≤ ListLength(L), *//* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 *///i的含义有两个://1、i是数列ai的i,从1~n的正整数//2、i是数组ai的i,从0~n-1的自然数,容器坐标,数组下标//要明白i的含义,根据下文题要可知,此操作为中插(头插+中插),所以i(0,size-1],所以i是坐标,数组下标Status ListInsert(SqList *L, int i, ElemType e){/* 顺序线性表已经满 */if (L->length == MAXSIZE)return ERROR;//原代码的i是正整数,此处是去掉头插,尾插//修改删除代码///* 当i不在范围内时 *///if (i < 1 || i >L->length + 1)// return ERROR;/* 若插入数据位置不在表尾 *///尾插不需要挪动数据元素,所以尾插与头插和中插的逻辑是不同的特殊的,所以无法统一//当i是坐标时//i = pos,i = 0即头插,i = ps->size即尾插//当i是正整数时//i = 1时是头插,i = ps->size+1时是尾插/* 若插入数据位置不在表尾 *///头插和中插//int k;//多弄出一个元素也还好,看似乎复杂,其实明了,k = end//if (i <= L->length){// /*将要插入位置后数据元素向后移动一位 */// for (k = L->length - 1; k >= i - 1; k--)// L->data[k + 1] = L->data[k];//}//当i是正整数时/* 将新元素插入 *///L->data[i - 1] = e;//L->length++;//用循环貌似更简单明了//多弄出一个元素也还好,看似乎复杂,其实明了,k = end//ListInsert(SqList *L, int i, ElemType e)int end = ps->size - 1;while (end >= i)//end是数组尾坐标{ps->a[end + 1] = ps->a[end];--end;}//当i是坐标时ps->a[i] = x;ps->size++;return OK;}//头插//全往后挪void SeqListPushFront(SL* ps, SLDateType x){assert(ps);SeqListCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];--end;}ps->a[0] = x;ps->size++;}//中插//比较复杂,需要考虑各种情况void SeqListInsert(SL* ps, int pos, SLDateType x){assert(ps);assert(pos <= ps->size && pos >= 0);//考虑各种情况,pos=0即头插,pos=ps->size即尾插SeqListCheckCapacity(ps);//凡是插入,必虑扩容//尾插不需要挪动数据元素,所以尾插与头插和中插的逻辑是不同的特殊的,所以无法统一int end = ps->size - 1;//pos=0即头插,pos=ps->size=end+1即尾插while (end >= pos)//end是数组尾坐标{ps->a[end + 1] = ps->a[end];--end;}ps->a[pos] = x;ps->size++;}//尾插void SeqListPushBack(SL* ps, SLDateType x){assert(ps);SeqListCheckCapacity(ps);ps->a[ps->size] = x;//从a[0]开始ps->size++;}
