第二章——线性表
4.对于顺序表L,指出以下算法的功能。
void fun(SqList * &L)
{ int i,j=0;
for (i=1;i<L->length;i++)
if (L->data[i] > L->data[j])
j=i;
for (i=j;i<L->length-1;i++)
L->data[i]=L->data[i+1];
L->length--;
}
/*
第一个循环:找到最大元素的下标 j(如果有多个相同最大值,找到的是第一个最大值的下标)。
第二个循环:从 j 到 length-2,将后面的元素前移,覆盖 data[j]。
表长减 1。
则该算法的功能是:删除顺序表中第一个最大值元素。
*/
5.对于顺序表L,指出以下算法的功能。
void fun(SqList * &L,ElemType x)
{ int i,j=0;
for (i=1;i<L->length;i++)
if (L->data[i] <= L->data[j])
j=i;
for (i=L->length;i>j;i--)
L->data[i]=L->data[i-1];
L->data[j]=x;
L->length++;
}
/*
第一个循环:找到最小元素的下标 j(如果有多个相同最小值,找到的是最后一个最小值的下标)。
第二个循环:将 j 位置及之后的元素后移一位。
在 j 位置插入 x。
表长加 1。
则该算法的功能是:在顺序表的最后一个最小值的位置插入元素 x。
*/
6.有人设计以下算法用于删除整数顺序表L中所有值在[x,y]的元素,该算法显然不是高效的,请设计一个同样功能的高效算法。
void fun(SqList * &L,ElemType x)
{ int i,j;
for (i=0;i<L->length;i++)
if (L->data[i] >= x && L->data[i] <= y)
{ for (j=1;j<L->length-1;j++)
L->data[j]=L->data[j+1];
L->length--;
}
}
/*
低效原因:每当找到一个在 [x, y] 的元素,就整体前移,时间复杂度 O(n^2)。
*/
void DeleteRange(SqList * &L, ElemType x, ElemType y)
{ int i, k = 0;
for (i = 0; i < L->length; i++) {
if (L->data[i] >= x && L->data[i] <= y) {
// 跳过,即不保留
} else {
L->data[k] = L->data[i];
k++;
}
}
L->length = k;
}
/*
高效思路:双指针法,一次扫描完成,时间复杂度 O(n)。
*/
7.设计一个算法,将x元素插到一个有序(从小到大排序)顺序表的适当位置,并保持有序性。
void InsertOrdered(SqList *&L, ElemType x)
{ int i;
// 1. 找到插入位置
for (i = 0; i < L->length; i++) {
if (L->data[i] > x) break;
}
// 2. 后移元素
for (int j = L->length; j > i; j--) {
L->data[j] = L->data[j - 1];
}
// 3. 插入 x
L->data[i] = x;
L->length++;
}