计划更新23王道数据结构所有课后代码习题的实现,虽然考试写的一般都是伪代码,但是强迫症的我还是全部实现了一遍,仓库在这里
代码全部是用 C++ 写的,都可以编译运行,包含暴力解和最优解。
持续更新,目前更新进度:
- 线性表 14/14
- 链表
- …
仅供参考! 会包含一些考试不让写的语法,可能也会有一些错误。
2.2.3, 08
- 暴力方法,再开一个数组,然后就是循环!
- 一次循环不行,两次!
- 参数 m 和 n 为两个线性表的长度
- 时间复杂度O(m+n),空间复杂度O(m+n)
void change(SqList &list, int m, int n) {
// 前一个线性表[0, m-1], 后一个[m, m+n-1]
SqList copied = list;
int k = -1;
for (int i = m; i < m+n; i++) {
copied.data[++k] = list.data[i];
}
for (int i = 0; i < m; i++) {
copied.data[++k] = list.data[i];
}
list = copied;
}
- 当然还有一种四两拨千斤的方法,可以先逆置整个数组,再分别逆置其中的两个线性表
- 比如说[1, 2, 3, 4]逆置成[4, 3, 2, 1],然后其中一个线性表[4, 3]逆置成[3, 4],另一个[2, 1]逆置成[1, 2],最后结果就是[3, 4, 1, 2]
- 时间复杂度O(m+n),空间复杂度O(1)
// 逆置,跟第二题类似, l=left, r=right
void reverse(SqList &list, int l, int r) {
if (l > r || r > list.length) return;
int mid = (l + r) / 2;
// 注意边界
for (int i = 0; i <= mid - l; i++) {
swap(list.data[l+i], list.data[r-i]);
}
}
void change2(SqList &list, int m, int n) {
// 注意参数
reverse(list, 0, m+n-1);
reverse(list, 0, n-1);
reverse(list, n, m+n-1);
}
2.2.3, 09
- 递增有序,暴力循环
- 需要考虑很多边界条件,容易出错
- 时间复杂度O(n),空间复杂度O(1)
void find_x2(SqList &list, int x) {
// 1.二分找x
int low = 0, high = list.length - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (list.data[mid] == x) break;
else if (list.data[mid] < x) low = mid + 1;
else high = mid - 1;
}
// 2.找到了
if (list.data[mid] == x && mid != list.length - 1) {
swap(list.data[mid], list.data[mid + 1]);
return;
}
// 3.没找到, 此时low>high
list.length++;
int i = list.length - 2