1. 顺序表的优点;
1. 无需为表示结点间的逻辑关系而增加额外存储空间;
2. 可以方便地随机存取表中的任一结点;
2. 顺序表的缺点;
1. 插入和删除运算不方便,必须移动大量的结点;
2. 顺序表要求占用连续的空间,存储分配只能预先进 行,因此当表长变化较大时,难以确定合适的存储规模;
3. 插入,在顺序表中插入指定的元素;
顺序表插入操作过程:将表中位置为n ,n-1,…上的结点,依次后移到位 置n+1,n,…上,当插入位置i=n+1时, 才无须移动结点,在该位置上插入新结点x,然后将该顺序表长度加1。
// 将元素x插入到顺序表L的第i个数据元素之前
void InsertSeqlist(SeqList L,DataType x, int i){
// 当表空间已满,不可再做插入操作
if (L.length==Maxsize) {exit("表已满")};
// 当插入位置为非法位置,不可做正常插入操作
if (i<1 || i>L.length+1) {exit("位置错")};
for(j = L.length;j>=i;j--) {
// 依次后移
L.data[j] = L.data[j-1];
};
// 元素x置入到下标为i-1的位置
L.data[i-1] = x;
// 表长度加1
L.length++;
}
插入算法的分析:假设线性表中含有 n 个数据元素, 在进行插入操作时,有 n+1 个位置可插入 。在每个位置插入数据的概率为1/(n+1) 。在 i 位置插入时,要移动 n-i+1 个数据 。假定在n+1个位置上插入元素的可能性均等, 则平均移动元素的个数为n/2。
4. 删除,在顺序表中删除指定的元素;
顺序表删除操作过程:若i=n,则只要删除终端结点,无须移动结点; 若1≤i≤n-1,则必须将表中位置 i+1,i+2,…,n的结点,依次前移到位置i, i+1,…,n-1上,以填补删除操作造成的空缺,最后该表长度减1。
// 删除线性表L中的第i个数据结点
void DeleteSeqList(SeqList L,int i) {
// 检查位置是否合法,如果非法位置,不能做正常的删除操作
if(i<1 || i>L.length){
exit("非法位置");
};
// 第i个元素的下标为i-1
for(j = i; j<L.length;j ++) {
// 依次左移
L.data[j-1] = L.data[j];
};
// 表长度减1
L.length--;
}
删除算法的分析:假设线性表中含有n个数据元素, 在进行删除操作时,有 n 位置可删除 。每个位置删除数据的概率是1/n。 在 i 位置删除时,要移动 n-i 个数据。 在进行删除操作时,若假定删除每个元素的可能性均等,则平均移动元素的个数为(n-1)/2。
5. 定位,查找顺序表中等于X的结点序号的最小值;
顺序表定位操作过程:从第一个元素 a1 起依次和x比较, 直到找到一个与x相等的数据元素,则返回它在顺序表中的存储下标或序号; 如果查遍整个表都没有找到与 x 相等的元素,返回0。
// 在顺序表中查找值为 x 的结点
int LocateSeqlist(SeqList L, DataType x){
int i=0;
while ((i<L. length) && (L.data[i]!=x) ) {
i++;
};
// 若找到值为x的元素,返回元素的序号
if(i<L.length) {
return i+1;
} else {
// 未查找到值为x的元素,返回0
return 0;
}
}
6. 插入、删除、定位实现算法分析总结;
在分析线性表的顺序表实现算法时,一个重要指标就是数据元素的比较和移动的次数。
1. 设表的长度length=n,在插入算法中,元素的移动次数不仅与顺序表的长度 n有关, 还与插入的位置i有关。插入算法在最坏情况下,其时间复杂度为O(n)。 一般情况下元素比较和移动的次数为n-i+1次,插入算法的平均移动次数约为n/2, 其时间复杂度是O(n);
2. 删除算法DeleteSeqlist,可得其在最坏情况下元素移动次数为n-1,时间复杂 度为O(n),元素平均移动次数约为(n-1)/2,时间复杂度为O(n);
3. 对于定位算法,需要扫描顺序表中的元素。以参数x与表中结点值的比较为 标准操作,平均时间复杂度为O(n)。求表长和读表元素算法的时间复杂度为O(1), 就阶数而言,己达到最低;