第二章-线性表算法题 笔记记录
- 1.从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
- 2. 设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
- 3. 对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为 O(1)的算法,该算法删除顺序表中所有值为x的数据元素。
- 4. 从顺序表中删除其值在给定值s和t之间(包含s和t,要求s<t)的所有元素,若s或t不合理或顺序表为空,则显示出错信息并退出运行。
- 5. 从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
- 6. 两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。
- 7. 知在一维数组A[m+n]中依次存放两个线性表(a1,a2,a3,⋯,am)和(b1,b2,b3,⋯,bn,)。编写个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,⋯,bn,)放在(a1,a2,a3,⋯,am)的前面。
- 8. 线性表(a1,a2,a3,⋯,an,)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换
- 9. 给定三个序列 A、B、C,长度均为 n,且均为无重复元素的递增序列,请设计一个时间上尽可能高效的算法,逐行输出同时存在于这三个序列中的所有元素。例如,数组A为{1,2,3],数组B为{2,3,4],数组C为{-1,0,2},则输出2。
- 10. 设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0、X1,⋯,Xn-1)变换为(Xp,Xp+1,⋯,Xn-1,X0,X1,⋯,Xp-1)
- 11. 一个长度为 L(L≥1)的升序序列S,处在第【L/2】个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S?的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在有两个等长升序序列 A和 B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。
- 12. 简而言之就是如果一个数组中出现的相同元素个数大于 list.length/2 则说明这个数是主元素,原题放图
- 13. 找出数组中的最小正整数
- 14. 三元组
1.从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
#include <iostream>
#define MAXSIZE 5
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool deleteMinElement(SeqList &seqList, int &value) {
if (seqList.length == 0) {
return false;
}
int pos = 0;
int minValue = seqList.data[0];
for (int i = 1; i < seqList.length; i++) {
if (seqList.data[i] < minValue) {
minValue = seqList.data[i];
pos = i;
}
}
seqList.data[pos] = seqList.data[seqList.length - 1];
value=minValue;
seqList.length--;
return true;
}
int main() {
SeqList seqList;
seqList.length = 5;
srand((unsigned) time(NULL));
for (int i = 0; i < seqList.length; i++) {
seqList.data[i] = rand() % 100;
printf("%d ", seqList.data[i]);
}
int value=0;
if (deleteMinElement(seqList, value)) {
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
printf("\n");
printf("最小值:%d", value);
} else {
printf("没有最小值\n");
}
return 0;
}
2. 设计一个高效算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
#include <iostream>
#define MAXSIZE 5
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
void invert(SeqList &seqList) {
for (int i = 0; i < seqList.length / 2; i++) {
int temp = seqList.data[i];
seqList.data[i] = seqList.data[seqList.length - 1 - i];
seqList.data[seqList.length - 1 - i] = temp;
}
}
int main() {
SeqList seqList;
seqList.length = 5;
srand((unsigned) time(NULL));
for (int i = 0; i < seqList.length; i++) {
seqList.data[i] = rand() % 100;
printf("%d ", seqList.data[i]);
}
invert(seqList);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
3. 对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为 O(1)的算法,该算法删除顺序表中所有值为x的数据元素。
#include <iostream>
#define MAXSIZE 5
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
void deleteX(SeqList &seqList, int x) {
int k = 0;
for (int i = 0; i < seqList.length; i++) {
if (seqList.data[i] != x) {
seqList.data[k++] = seqList.data[i];
}
}
seqList.length = k;
}
void deleteX2(SeqList &seqList, int x) {
int k = 0, i = 0;;
while (i < seqList.length) {
if (seqList.data[i] == x) {
k++;
} else {
seqList.data[i - k] = seqList.data[i];
}
i++;
}
seqList.length -= k;
}
int main() {
SeqList seqList;
seqList.length = 5;
srand((unsigned) time(NULL));
for (int i = 0; i < seqList.length; i++) {
seqList.data[i] = rand() % 10;
printf("%d ", seqList.data[i]);
}
deleteX(seqList, 5);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
4. 从顺序表中删除其值在给定值s和t之间(包含s和t,要求s<t)的所有元素,若s或t不合理或顺序表为空,则显示出错信息并退出运行。
#include <iostream>
#define MAXSIZE 5
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool deleteRange(SeqList &seqList, int s, int t) {
if (s >= t || seqList.length == 0) {
return false;
}
int k = 0;
for (int i = 0; i < seqList.length; i++) {
if (seqList.data[i] < s || seqList.data[i] > t) {
seqList.data[k++] = seqList.data[i];
}
}
seqList.length = k;
return true;
}
bool deleteRange2(SeqList &seqList, int s, int t) {
int k = 0, i = 0;
if (s >= t || seqList.length == 0) {
return false;
}
for (int i = 0; i < seqList.length; i++) {
if (seqList.data[i] >= s && seqList.data[i] <= t) {
k++;
} else {
seqList.data[i - k] = seqList.data[i];
}
}
seqList.length -= k;
return true;
}
int main() {
SeqList seqList;
seqList.length = 5;
srand((unsigned) time(NULL));
for (int i = 0; i < seqList.length; i++) {
seqList.data[i] = rand() % 10;
printf("%d ", seqList.data[i]);
}
deleteRange(seqList, 2, 5);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
5. 从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同。
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool deleteRepeat(SeqList &seqList) {
if (seqList.length == 0) {
return false;
}
int k=0;
for (int i=1; i < seqList.length; i++) {
if (seqList.data[k] != seqList.data[i]) {
seqList.data[++k] = seqList.data[i];
}
}
seqList.length = k + 1;
return true;
}
int main() {
SeqList seqList={1, 1, 1, 2, 2, 3, 3, 3, 4, 4};
seqList.length = 10;
deleteRepeat(seqList);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
6. 两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool mergeSeqList(SeqList &seqList1, SeqList &seqList2, SeqList &seqList3) {
if (seqList1.length + seqList2.length > seqList3.length) {
return false;
}
seqList3.length = seqList1.length + seqList2.length;
int i = 0, j = 0, k = 0;
while (i < seqList1.length && j < seqList2.length) {
if (seqList1.data[i] < seqList2.data[j]) {
seqList3.data[k++] = seqList1.data[i++];
} else {
seqList3.data[k++] = seqList2.data[j++];
}
}
while (i < seqList1.length) {
seqList3.data[k++] = seqList1.data[i++];
}
while (j < seqList2.length) {
seqList3.data[k++] = seqList2.data[j++];
}
seqList3.length=k;
return true;
}
int main() {
SeqList seqList = {1, 1, 2, 3, 3, 4, 5, 6, 7, 8};
SeqList seqList2 = {1, 2,3,5};
seqList.length = 10;
seqList2.length = 4;
SeqList seqList3;
mergeSeqList(seqList, seqList2, seqList3);
printf("\n");
for (int i = 0; i < seqList3.length; i++) {
printf("%d ", seqList3.data[i]);
}
return 0;
}
7. 知在一维数组A[m+n]中依次存放两个线性表(a1,a2,a3,⋯,am)和(b1,b2,b3,⋯,bn,)。编写个函数,将数组中两个顺序表的位置互换,即将(b1,b2,b3,⋯,bn,)放在(a1,a2,a3,⋯,am)的前面。
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool invert2(SeqList &seqList, int left, int right) {
if (left > right) {
return false;
}
while (left < right) {
int temp = seqList.data[left];
seqList.data[left] = seqList.data[right];
seqList.data[right] = temp;
left++;
right--;
}
return true;
}
bool swap(SeqList &seqList, int m, int n) {
if (m + n > seqList.length) {
return false;
}
invert2(seqList, 0, m + n-1);
invert2(seqList, 0, n-1);
invert2(seqList, n, m + n-1);
seqList.length = m + n;
return true;
}
int main() {
SeqList seqList = {1, 2, 3, 4, 5, 6,7};
seqList.length = 7;
swap(seqList, 3, 4);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
8. 线性表(a1,a2,a3,⋯,an,)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找数值为x的元素,若找到,则将其与后继元素位置相交换
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool searchAndSwap(SeqList &seqList, int x) {
int low = 0, high = seqList.length - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (seqList.data[mid] == x) {
break;
} else if (seqList.data[mid] < x) {
low = mid + 1;
} else {
high = mid - 1;
}
}
if (seqList.data[mid] == x && mid != seqList.length - 1) {
int temp = seqList.data[mid];
seqList.data[mid] = seqList.data[mid + 1];
seqList.data[mid + 1] = temp;
}
if (low > high) {
seqList.length++;
int i;
for ( i = seqList.length - 1; i > high; i--) {
seqList.data[i + 1] = seqList.data[i];
}
seqList.data[high + 1] = x;
}
return true;
}
int main() {
SeqList seqList = {1, 3, 3, 4, 4, 6, 7};
seqList.length = 7;
searchAndSwap(seqList, 5);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
9. 给定三个序列 A、B、C,长度均为 n,且均为无重复元素的递增序列,请设计一个时间上尽可能高效的算法,逐行输出同时存在于这三个序列中的所有元素。例如,数组A为{1,2,3],数组B为{2,3,4],数组C为{-1,0,2},则输出2。
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
int getMaxValue(int a, int b) {
return a > b ? a : b;
}
bool printCommonElement(SeqList &seqList1, SeqList &seqList2, SeqList &seqList3) {
int i = 0, j = 0, k = 0;
while (i < seqList1.length && j < seqList2.length && k < seqList3.length) {
if (seqList1.data[i] == seqList2.data[j] && seqList2.data[j] == seqList3.data[k]) {
printf("%d ", seqList1.data[i]);
i++;
j++;
k++;
} else {
int max=getMaxValue(seqList1.data[i],getMaxValue(seqList2.data[j],seqList3.data[k]));
if (seqList1.data[i]<max) i++;
if (seqList2.data[j]<max) j++;
if (seqList3.data[k]<max) k++;
}
}
}
int main() {
SeqList seqList = {1, 3, 4};
SeqList seqList2 = {1, 2, 3};
SeqList seqList3 = {-1, 2, 3};
seqList.length = 3;
seqList2.length = 3;
seqList3.length = 3;
printCommonElement(seqList, seqList2, seqList3);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
10. 设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移p(0<p<n)个位置,即将R中的数据由(X0、X1,⋯,Xn-1)变换为(Xp,Xp+1,⋯,Xn-1,X0,X1,⋯,Xp-1)
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool invert2(SeqList &seqList, int left, int right) {
if (left > right) {
return false;
}
while (left < right) {
int temp = seqList.data[left];
seqList.data[left] = seqList.data[right];
seqList.data[right] = temp;
left++;
right--;
}
return true;
}
bool leftMove(SeqList &seqList, int p) {
if (p <= 0 || p >= seqList.length) {
return false;
}
invert2(seqList, 0, p-1);
invert2(seqList, p, seqList.length-1);
invert2(seqList, 0, seqList.length-1);
return true;
}
int main() {
SeqList seqList = {0, 1, 2,3,4};
seqList.length = 5;
leftMove(seqList,4);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
11. 一个长度为 L(L≥1)的升序序列S,处在第【L/2】个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19),则S?的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在有两个等长升序序列 A和 B,试设计一个在时间和空间两方面都尽可能高效的算法,找出两个序列A和B的中位数。
#include <iostream>
#define MAXSIZE 50
typedef struct {
int data[MAXSIZE];
int length;
} SeqList;
bool getMedian(SeqList &seqList1, SeqList &seqList2) {
int sumLength = seqList1.length + seqList2.length;
int mid = sumLength / 2;
int k = 0;
int i = 0, j = 0;
while (k < mid) {
if (seqList1.data[i] < seqList2.data[j]) {
i++;
k++;
if (k == mid) {
printf("%d", seqList1.data[i - 1]);
}
} else {
j++;
k++;
if (k == mid) {
printf("%d", seqList2.data[j - 1]);
}
}
}
return true;
}
int main() {
SeqList seqList = {1, 2, 5, 7, 9, 11};
SeqList seqList2 = {1, 2, 4, 6, 8, 9};
seqList.length = 6;
seqList2.length = 6;
getMedian(seqList2, seqList);
printf("\n");
for (int i = 0; i < seqList.length; i++) {
printf("%d ", seqList.data[i]);
}
return 0;
}
12. 简而言之就是如果一个数组中出现的相同元素个数大于 list.length/2 则说明这个数是主元素,原题放图
int getMajorityElement(SeqList &seqList) {
int count = 0;
int value = seqList.data[0];
for (int i = 0; i < seqList.length; i++) {
if (seqList.data[i] == value) {
count++;
} else {
count--;
}
if (count == 0) {
value = seqList.data[i];
count = 1;
}
}
count = 0;
for (int i = 0; i < seqList.length; i++) {
if (seqList.data[i] == value) {
count++;
}
}
if (count > seqList.length / 2) {
printf("主元素是:%d", value);
return value;
} else {
return -1;
}
}
13. 找出数组中的最小正整数
int getMinPositiveInteger(SeqList &seqList) {
int n = seqList.length;
SeqList B;
B.length = n;
for (int i = 0; i < n; i++) {
B.data[i] = 0;
}
int i;
for (i = 0; i < seqList.length; i++) {
if (seqList.data[i] > 0 && seqList.data[i] <= n) {
B.data[seqList.data[i] - 1] = 1;
}
}
for (int i = 0; i < n; i++) {
if (B.data[i] == 0) {
printf("最小正整数是:%d", i + 1);
return i + 1;
}
}
}
14. 三元组
int abs(int a) { return a < 0 ? -a : a; }
int GetMinDistance(int a[], int aa, int b[], int bb, int c[], int cc) {
int min = 10000000;
for (int i = 0; i < aa; i++) {
for (int j = 0; j < bb; j++) {
for (int k = 0; k < cc; k++) {
int d = 0;
d = abs(a[i] - b[j]) + abs(b[j] - c[k]) + abs(c[k] - a[i]);
if (min > d) {
min = d;
}
}
}
}
return min;
}
int main() {
int a[3]={-1,0,9};
int b[4]={-25,-10,10,11};
int c[5]={2,9,17,30,41};
printf("最小距离为:%d\n",GetMinDistance(a,3,b,4,c,5));
return 0;
}