数据结构-王道2017-第2章 线性表-2.2 综合应用题
1. 顺序表中删除最小值的元素,并由函数返回被删除元素的值,空出的位置由最后一个元素填补,顺序表为空则显示出错信息并退出运行。
bool DelMin(SqList& L, ElemType & value){ if(L.length == 0){ puts("顺序表不能为空"); return false; } int value = L.data[0]; int pos ; for(int i = 1;i < L.length;i++){ if(value > L.data[i]){ value = L.data[i]; pos = i; } } L.data[j] = L.data[L.length - 1]; L.length--; //重要,长度不能忽略 return true; }
2. 设计一个高效的算法,将顺序表中所有元素逆置,要求算法的时间复杂度为O(1)
将前L.length/2的元素与后半部分的元素交换,而奇数个的中节点不用和其他元素交换
1 void Reverse(SqList &L){ 2 3 ElemType temp; 4 5 for(int i = 0; i < (L.length/2);i++){ 6 temp = L.data[i]; //只是用了一个临时变量,空间复杂度为O(1) 7 L.data[i] = L.data[L.length - 1 - i]; 8 L.data[L.length - 1 - i] = temp; 9 10 } 11 12 }
3.长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素
(1)用k记录顺序表中不等于x的元素个数(即需要保存的元素个数),边扫描边统计k,并将不等于x的元素防止在k位置上。
void delX(SqList &L, ElemType x){ int k = 0; for(int i = 0; i < L.length;i++) if(L.data[i] != x){ L.data[k] = L.data[i]; k++; } L.length = k; }
(2) 用k记录顺序表中等于x的元素个数,边扫描边统计k,并将不等于k的元素向前移动k个位置。
void delX(SqList &L, ElemType x){ int k = 0; for(int i = 0; i < L.length;i++){ if(L.data[i] == x){ k++; }else{ L.data[i-k] = L.data[i]; //当前元素前移k个位置 } } L.length -= k; }
4. 从有序表中删除其值在给定值s与t之间(要求s<t)的所有元素,如果s或t不合理或者顺序表为空则显示出错信息并退出运行
1 /* 未完成 2 bool delst(SqList & L, ElemType s, ElemType t){ 3 if(L.length == 0 || !(s < t) ) 4 return false; 5 int l = 0, r =L.length-1; 6 int mid = -1; 7 bool flag = false; 8 while(l <= r){ 9 mid = (l+r)/2; 10 11 if(L.data[mid] > s) 12 r = mid - 1; 13 else if(L.data[mid] < s) 14 l = mid + 1; 15 else { 16 l = mid; 17 flag = true; 18 break; 19 } 20 21 } 22 if(!flag){ 23 if(l > r && s > []) 24 else return false; 25 } 26 27 28 } 29 */
5.从顺序表中删除其值在给定值s与t之间,(包含s和t,要求s<t)的所有元素,如果s或t不合理或者顺序表为空则显示出错信息并退出运行
bool delSt(SqList &L, ElemType s,Elemtype t){ if(L.length == 0 || s >= t) return false; int k = 0; //保存被删除的个数 for(int i = 0;i < L.length;i++){ if(L.data[i] >= s && L.data[i] <= t ) k++; else L.data[i-k] = L.data[i]; } L.length -= k; return true; }
6.从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同
//因为有序,所以必在相邻位置上 bool delSame(SqList &L){ if(L.length == 0) return false; int k = 0,temp = L.data[0]; for(int i =1 ;i < L.length;i++){ if(temp==L.data[i]){ k++; }else{ temp = L.data[i]; L.data[i-k] = L.data[i]; } } L.length -= k; return true; }
bool delSame(SqList& L){ if(L.length == 0) return false; int i = 0,j = 1; for(;j < L.length;j++){ if(L.data[i] != L.data[j]) L.data[++i] = L.data[j]; //将不相等的值前移 } L.length = i + 1; //i从0开始计数
return true; }
7.将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表
8.已知在一维数组A[m+n]中一次有两个线性表,编写一个函数,将两个顺序表的位置互换
思路:先将数组整体原地置换,即m与n置换,在对m和n进行内部置换
void reverse(ElemType A[],int left, int right,int arraySize) { if (left >= right || right >= arraySize) return; int mid = (left + right) / 2; for (int i = 0; i <= mid - left; i++) { ElemType temp = A[left + i]; A[left + i] = A[right - i]; A[right - i] = temp; } } void Exchange(ElemType A[],int m,int n,int arraySize) { reverse(A,0,m+n-1,arraySize); reverse(A, 0, n - 1, arraySize); reverse(A, n, m + n - 1, arraySize); }
9.线性表(a1,a2..an)递增有序请在最少时间在表中查找数值为x的元素,若找到,将其与后继元素交换,若找不到将其插入表中并使表中元素有序
bool findOrInsert(ElemType A[], ElemType x,int n) { int low = 0, high = n - 1,mid; while (low <= high) { mid = (low + high) / 2; if (A[mid] == x) { if (mid != n - 1) { //交换条件,不能把此条件跟上面的if用&&连接,否则会造成死循环 ElemType temp = A[mid]; A[mid] = A[mid + 1]; A[mid + 1] = temp; } return true; } else if (A[mid] < x) low = mid + 1; else if (A[mid] > x) high = mid - 1; } //未找到则low已经大于high,A[high] < x,而A[low] 要么大于x,要么不存在(low == n)即x必定被插入到下标high之后 for (int i = n - 1; i > high; i--) A[i + 1] = A[i]; A[high + 1] = x; //插入x到high之后 return false; }