加载头像

2023-12-08竞赛笔记

2023/12/8

GESP C++等级测试四级2023 年 6 ⽉


希尔排序(递减增量排序)




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename T>
void shell_sort(T array[], int length) {
int h = 1;
while (h < length / 3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (int i = h; i < length; i++) {
for (int j = i; j >= h && array[j] < array[j - h]; j -= h) {
std::swap(array[j], array[j - h]);
}
}
h = h / 3;
}
}

归并排序

代码1(数组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void merge(const int *a, size_t aLen, const int *b, size_t bLen, int *c) {
size_t i = 0, j = 0, k = 0;
while (i < aLen && j < bLen) {
if (b[j] < a[i]) { // <!> 先判断 b[j] < a[i],保证稳定性
c[k] = b[j];
++j;
} else {
c[k] = a[i];
++i;
}
++k;
}
// 此时一个数组已空,另一个数组非空,将非空的数组并入 c 中
for (; i < aLen; ++i, ++k) c[k] = a[i];
for (; j < bLen; ++j, ++k) c[k] = b[j];
}

代码2(指针)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void merge(const int *aBegin, const int *aEnd, const int *bBegin,
const int *bEnd, int *c) {
while (aBegin != aEnd && bBegin != bEnd) {
if (*bBegin < *aBegin) {
*c = *bBegin;
++bBegin;
} else {
*c = *aBegin;
++aBegin;
}
++c;
}
for (; aBegin != aEnd; ++aBegin, ++c) *c = *aBegin;
for (; bBegin != bEnd; ++bBegin, ++c) *c = *bBegin;
}

//也可使用 <algorithm> 库的 merge 函数,用法与上述指针式写法的相同。

1
2
3
4
5
6
7
8
9
10
11
void merge_sort(int *a, int l, int r) {
if (r - l <= 1) return;
// 分解
int mid = l + ((r - l) >> 1);
merge_sort(a, l, mid), merge_sort(a, mid, r);
// 合并
int tmp[1024] = {}; // 请结合实际情况设置 tmp 数组的长度(与 a 相同),或使用
// vector;先将合并的结果放在 tmp 里,再返回到数组 a
merge(a + l, a + mid, a + mid, a + r, tmp + l); // pointer-style merge
for (int i = l; i < r; ++i) a[i] = tmp[i];
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void merge_sort(int *a, size_t n) {
int tmp[1024] = {}; // 请结合实际情况设置 tmp 数组的长度(与 a 相同),或使用
// vector;先将合并的结果放在 tmp 里,再返回到数组 a
for (size_t seg = 1; seg < n; seg <<= 1) {
for (size_t left1 = 0; left1 < n - seg;
left1 += seg + seg) { // n - seg: 如果最后只有一个段就不用合并
size_t right1 = left1 + seg;
size_t left2 = right1;
size_t right2 = std::min(left2 + seg, n); // <!> 注意最后一个段的边界
merge(a + left1, a + right1, a + left2, a + right2,
tmp + left1); // pointer-style merge
for (size_t i = left1; i < right2; ++i) a[i] = tmp[i];
}
}
}


avatar
status
这有关于产品、设计、开发相关的问题和看法,还有文章翻译分享
相信你可以在这里找到对你有用的知识教程
公告

Minecraft-Sep的博客已更新至v1.6.0版本!
基于CodebergVercelCloudflare的Sep博客已上线!详情见此处!
您正在浏览安全的Pages页面!

引用到评论
随便逛逛博客分类文章标签
复制地址关闭热评深色模式轉為繁體