线性表的顺序表示和实现
1.顺序表的定义
将表中元素一个接一个的存入一组连续的存储单元中,这种存储结构是顺序结构。
采用顺序存储结构的线性表简称为“ 顺序表”。
在顺序表中逻辑结构上相邻的数据元素,其物理位置(存储地址)也是相邻的。
2.顺序表中数据元素的存储地址
若一个数据元素仅占一个存储单元,其存储方式为:
存储地址 | 内容 | 元素序号 |
---|---|---|
L | a1 | 1 |
L+1 | a1 | 2 |
… | … | … |
L+(i-1) | ai | i |
… | … | … |
L+(n-1) | an | n |
从表可知,第i个元素地址为:
L(ai)=L(a1)+(i-1)
若每个数据元素占用m个存储单元,第i个元素地址为:
L(ai)=L(a1)+(i-1)*m
显然,在顺序表中逻辑结构上相邻的数据元素,其物理位置(存储地址)也是相邻的。
3.顺序表的表示
以C语言为例
#idefine M 10
int a[M];
顺序表C语言中的一维数组实现。
4.顺序表的基本运算
1.插入运算
建立一个长度为n的顺序表,其中ai为第i个元素(0<=i<=n)。
在第i个数据元素前插入一个新的数据元素x。新的顺序表长度变为(n+1)。
插入算法思想:
若表长n<0或插入位置不当,则输出信息提示,并返回-1。
当0<=i<=n时,则从表尾元素开始到第i个元素依次向后移动一个位置(共需移动n-i+1跟元素)。
最后将x存入ai中,表长为n+1插入成功,函数返回值为0。
C语言实现(函数可直接调用):
int sxbcr(int a[],int i,int x)
{
int j;
int n=0;
n=sizeof(a)/sizeof(int);/*n为a[]长度*/
if (n<0)
{printf("表长错误\n");
return(-1);
}
if (i<1||i>n+1)
{printf("插入位置i不适当\n");
return(-1);
}
for (j=n;j>=i;j--)
a[j+1]=a[j];
a[j]=x;
n++;
printf("success\n");
return 0;
}
- 插入算法分析:
上述算法for循环语句的执行次数为n-i+1;
若i=1,需移动全部n个结点(最坏:O(n))
若i=n+1(在表尾插入),无需用移动结点,直接插入即可。(最好O(1))
移动结点的平均次数:
- 按等概率考虑:
可能插入的位置为i=1,2,…,n,n+1。共n+1个,则Pi=1/(n+1),所以
- 顺序表的插入算法平均需移动 n/2 结点。
2.删除算法
建立一个长度为n的顺序表,其中ai为第i个元素(0<=i<=n)。
将第i个数据元素删除。新的顺序表长度变为(n-1)。
删除算法思想:
若i=n,只需删除终端结点,不用移动结点;
若表长度n<=0或删除位置不当,则输出错误信息,并返回-1;
当1<=i<n时,则将表中结点ai+1,ai+2,…,an依次向前移动一个位置(共需移动n-i个数据元素)。
最后将表长n减1,删除成功,函数返回值为0。
C语言实现(函数可直接调用):
int deleteList(int a[],int i)
{
int j;
int n=0;
n=sizeof(a)/sizeof(int);/*n为a[]长度*/
if (n<0){
printf("表长错误\n");
return(-1);
}
if(i<1 || i>n){
printf("删除位置i不适当\n");
return -1;
}
for(j=i+1;j<=n;j++)
a[j-1]=a[j];
n--;
printf("success\n");
return 0;
}
删除算法分析:
与插入算法同理,可推出移动结点的平均次数为(n-1)/2。
顺序表插入、删除算法平均约需移动一半结点,当n很大时,算法的效率较低。
5.顺序表的优缺点
- 优点
(1)无须为表示结点间的逻辑关系而增加额外的存储空间。
(2)可以方便地随机存储表中的任一结点。 - 缺点:
(1)插入和删除平均须移动一半结点。
(2)存储分配只能预先进行(静态)。
文章内容来源于博主老师传授、自身理解以及网络收集