顺序表的插入操作

428 阅读3分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情

一.线性表的顺序表示

1.顺序表的定义

  1. 线性表又称顺序表,用一组地址连续的存储单元来依次存储线性表中的数据元素,使得逻辑上相邻的元素在物理位置上也相邻。
  2. 线性表(顺序表)的特点:元素的逻辑顺序和物理顺序相同。逻辑上相邻的元素在物理上也相邻,删除或者插入操作需要移动大量的元素。
  3. 线性表(顺序表)中任意一个元素都可以进行随机存取(访问)。通过首地址以及元素序号可以在O(1)O(1)的时间内找到指定的元素。
  4. 通常在高级程序语言中用数组来表述线性表(顺序表)。
  5. i是元素aiai在线性表(顺序表)中的位序。线性表(顺序表)中元素是从1开始的,而数组元素的下标是从0开始的。
  6. 顺序表存储密度高,每个结点只存储数据元素。

假设线性表的元素类型是ElemType,那么线性表的顺序存储类型描述为:

#define MaxSize 50  //定义线性表的最大长度
typedef struct{
ElemType data[MaxSize];//顺序表的元素
int length;//顺序表的当前长度
}SqList;//顺序表的类型定义

我们知道一维数组可以用静态分配也可以用动态分配。

静态分配:数组的大小以及空间事先已经确定,加入新的数据会发生产生溢出。

动态分配:数组的空间是在程序执行的过程中通过动态分配语句进行分配的,不会产生溢出,一旦出现溢出另外开辟一块更大的存储空间即可。无需一次性的划分所有的空间。

#define InitSize 100//表长度的初始定义
typedef struct{
ElemTypde *data;//指示动态分配数组的指针
int MaxSize,length;//数组的最大容量和当前个数
}SqList;//动态分配数组顺序表的类型定义

C的初始动态分配语句:

L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);

c++的初始动态分配语句:

L.data=new ElemType[InitSize];

注意:动态分配还是顺序存储结构,物理结构并没有发生变化,仍然是随机存储的方式,只是分配的空间大小可以在运行过程中动态决定。

2.顺序表上的基本操作的实现

1.插入操作

操作描述:在顺序表(线性表)L的第i个位置插入新的元素e。如果对于i输入的不合法,就返回false,表示插入失败。否则,将第i个元素以及后面的元素依次向后移一个位置,空出一个位置插入新的元素e,顺序表的长度增加1,插入成功返回true。

bool ListInsert(SqList &L,int i,ElemType e){

if(i<1||i>L.length)//判断i是否合法
return false;

if(L.length>=MaxSize)//当前存储空间已满,插入失败
return false;

for(int j=L.length;j>=i;j--)//将第i个元素以及之后的元素后移
L.data[j]=L.data[j-1];
L.data[i-1]=e;//将位置i处放e
L.length++;//线性表长度加1
retur true;
}

  • 最好情况:在表尾插入元素(也就是i=n+1),元素后移的语句不执行,时间复杂度为O(n)O(n)
  • 最坏情况:在表头插入(也就是i=1),元素后移语句将执行n次,时间复杂度为O(n)O(n)
  • 平均情况:假设pi=1/(n+1)pi=1/(n+1),所需要移动结点的平均次数为n/2

综上总结:线性表(顺序表)插入算法的时间复杂度为O(n)O(n)

删除操作

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 9 天,点击查看活动详情