归并排序
分治到单元素,再两两合并成有序段
前置内容
正文
// ── 归并排序:分治 + 合并 ──
// 稳定排序,O(n log n)
// 需要 O(n) 辅助空间
int tmp[100005];
void merge_sort(int a[], int l, int r) {
// 单个元素不用排
if (l >= r) return;
int mid = (l + r) / 2;
// 先排好左半
merge_sort(a, l, mid);
// 再排好右半
merge_sort(a, mid + 1, r);
// 左指针、右指针、写入位置
int i = l, j = mid + 1, k = l;
while (i <= mid && j <= r) {
// 两头取小的写入;
// 相等取左边 → 稳定性的来源
tmp[k++] = a[i] <= a[j]
? a[i++] : a[j++];
}
// 左边剩下的直接搬
while (i <= mid) tmp[k++] = a[i++];
// 右边剩下的直接搬
while (j <= r) tmp[k++] = a[j++];
// 写回原数组
for (int p = l; p <= r; p++)
a[p] = tmp[p];
}
// 归并排序还能顺便数逆序对
// CSP 常考
CSP-J · 编程模板的其它内容
- 输出一句话
- 两数求和
- 矩形周长与面积
- 圆的面积
- 三数求平均值
- 摄氏转华氏
- 三位数各位拆分
- 简单本息
- 交换两个数
- 圆的周长与面积
- 三角形面积
- 梯形面积
- 长方体体积
- 英里转公里
- 总秒数换算分秒
- 商品总价与找零
- 存储单位与数据规模
- 字符编码与 ASCII
- 位运算
- 原码反码补码
- 进制转换
- 数据范围与溢出
- 时间复杂度估算
- 初赛程序阅读技巧
- 变量与数据类型
- 输入输出
- 运算符与表达式
- 分支 if/switch
- 基础循环
- 数组遍历
- 字符数组与 string
- 函数与参数传递
- 全局变量与局部变量
- 类型转换与取整
- 文件读写 freopen
- 结构体
- 指针与引用
- vector 动态数组
- string 常用操作
- algorithm 常用算法
- pair 与自定义排序
- stack 栈
- queue 队列
- priority_queue 优先队列
- set 集合
- map 映射
- lower_bound 二分
- next_permutation 全排列
- 枚举法
- 模拟
- 递归求阶乘
- 求素数
- 埃氏筛素数表
- 前缀和
- 差分
- 冒泡排序
- 插入排序
- 快速排序
- 双指针
- 贪心