刚才我们也谈到,这里的时间复杂度为O(1)。我们现在来考虑,如果我们要实现ListIn-sert(*L,i,e),即在线性表L中的第i个位置插入新元素e,应该如何操作?
    举个例子,本来我们在春运时去买火车票,大家都排队排的好好的。这时来了一个美女,对着队伍中排在第三位的你说,“大哥,求求你帮帮忙,我家母亲有病,我得急着回去看她,这队伍这么长,你可否让我排在你的前面?”你心一软,就同意了。这时,你必须得退后一步,否则她是没法进到队伍来的。这可不得了,后面的人像蠕虫一样,全部都得退一步。骂声四起。但后面的人也不清楚这加塞是怎么回事,没什么办法。
    这个例子其实已经说明了线性表的顺序存储结构,在插入数据时的实现过程
    (如图所示)。
    image.png插入算法的思路:

    • 如果插入位置不合理,抛出异常;
    • 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;
    • 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;
    • 将要插入元素填入位置i处; ?表长加1。

    实现代码如下:
    //2.动态顺序表实践,2.4指定位置插入数据https://www.yuque.com/muzichenqing/wpdm33/qrkb1f

    1. /* 初始条件:顺序线性表L已存在,1 ≤ i ≤ ListLength(L), */
    2. /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
    3. //i的含义有两个:
    4. //1、i是数列ai的i,从1~n的正整数
    5. //2、i是数组ai的i,从0~n-1的自然数,容器坐标,数组下标
    6. //要明白i的含义,根据下文题要可知,此操作为中插(头插+中插),所以i(0,size-1],所以i是坐标,数组下标
    7. Status ListInsert(SqList *L, int i, ElemType e)
    8. {
    9. /* 顺序线性表已经满 */
    10. if (L->length == MAXSIZE)
    11. return ERROR;
    12. //原代码的i是正整数,此处是去掉头插,尾插
    13. //修改删除代码
    14. ///* 当i不在范围内时 */
    15. //if (i < 1 || i >L->length + 1)
    16. // return ERROR;
    17. /* 若插入数据位置不在表尾 *///尾插不需要挪动数据元素,所以尾插与头插和中插的逻辑是不同的特殊的,所以无法统一
    18. //当i是坐标时
    19. //i = pos,i = 0即头插,i = ps->size即尾插
    20. //当i是正整数时
    21. //i = 1时是头插,i = ps->size+1时是尾插
    22. /* 若插入数据位置不在表尾 *///头插和中插
    23. //int k;//多弄出一个元素也还好,看似乎复杂,其实明了,k = end
    24. //if (i <= L->length){
    25. // /*将要插入位置后数据元素向后移动一位 */
    26. // for (k = L->length - 1; k >= i - 1; k--)
    27. // L->data[k + 1] = L->data[k];
    28. //}
    29. //当i是正整数时
    30. /* 将新元素插入 */
    31. //L->data[i - 1] = e;
    32. //L->length++;
    33. //用循环貌似更简单明了//多弄出一个元素也还好,看似乎复杂,其实明了,k = end
    34. //ListInsert(SqList *L, int i, ElemType e)
    35. int end = ps->size - 1;
    36. while (end >= i)//end是数组尾坐标
    37. {
    38. ps->a[end + 1] = ps->a[end];
    39. --end;
    40. }
    41. //当i是坐标时
    42. ps->a[i] = x;
    43. ps->size++;
    44. return OK;
    45. }
    46. //头插//全往后挪
    47. void SeqListPushFront(SL* ps, SLDateType x)
    48. {
    49. assert(ps);
    50. SeqListCheckCapacity(ps);
    51. int end = ps->size - 1;
    52. while (end >= 0){
    53. ps->a[end + 1] = ps->a[end];
    54. --end;
    55. }
    56. ps->a[0] = x;
    57. ps->size++;
    58. }
    59. //中插//比较复杂,需要考虑各种情况
    60. void SeqListInsert(SL* ps, int pos, SLDateType x)
    61. {
    62. assert(ps);
    63. assert(pos <= ps->size && pos >= 0);//考虑各种情况,pos=0即头插,pos=ps->size即尾插
    64. SeqListCheckCapacity(ps);//凡是插入,必虑扩容
    65. //尾插不需要挪动数据元素,所以尾插与头插和中插的逻辑是不同的特殊的,所以无法统一
    66. int end = ps->size - 1;
    67. //pos=0即头插,pos=ps->size=end+1即尾插
    68. while (end >= pos)//end是数组尾坐标{
    69. ps->a[end + 1] = ps->a[end];
    70. --end;
    71. }
    72. ps->a[pos] = x;
    73. ps->size++;
    74. }
    75. //尾插
    76. void SeqListPushBack(SL* ps, SLDateType x)
    77. {
    78. assert(ps);
    79. SeqListCheckCapacity(ps);
    80. ps->a[ps->size] = x;//从a[0]开始
    81. ps->size++;
    82. }