5 归并排序

归并排序基于分治思想将数组分段排序后合并,时间复杂度在最优、最坏与平均情况下均为 \(\Theta (n \log n)\),空间复杂度为 \(\Theta (n)\)

归并排序可以只使用 \(\Theta (1)\) 的辅助空间,但为便捷通常使用与原数组等长的辅助数组.(摘自 OI Wiki

让我们来模拟一下排序过程:

原序列:\(1 6 2 7 9 2 5 3\)

两两一组:\(16 \ 2 7 \ 9 2 \ 5 3\)

每一组内进行排序后:\(16 \ 2 7 \ 2 9 \ 3 5\)

两组合并为一组:\(1267 \ 2359\)

两组合并为一组:\(12235679\)

正规的归并排序是先分割成两两一组,再将组内排序,最后合并变成有序的序列。

代码实现

可以参考 OI Wiki 中的实现,通常使用递归、分治的算法。

6 sort 等

\(a\) 数组排序其实可以这么写 sort(a+1,a+n+1,xxx);。底层实现为快速排序。

其中的 xxx 是排序方法。可以是自定义的,也可以是别的。比如说:

  1. 不写:升序排序。
  2. greater<数据类型>():降序排序。
  3. cmp:自定义。

在结构体排序时,一般使用运算符重载和 cmp。示例:

bool cmp(node &u,node &v){//node 为结构体类型
	if(u.a!=v.a) return u.a<v.a;//按 a 排序
	return u.b<v.b;//a 相等,按 b 排序
}

运算符重载也差不多。

当然除了 sort,也有 stable_sort,底层为归并排序。

例题(洛谷 P1177)

题目描述

将读入的 \(N\) 个数从小到大排序后输出。

输入格式

第一行为一个正整数 \(N\)

第二行包含 \(N\) 个空格隔开的正整数 \(a_i\),为你需要进行排序的数。

输出格式

将给定的 \(N\) 个数从小到大输出,数之间空格隔开。

输入输出样例 #1
输入 #1
5
4 2 4 5 1
输出 #1
1 2 4 4 5
说明/提示

对于 \(20\%\) 的数据,有 \(1 \leq N \leq 10^3\)

对于 \(100\%\) 的数据,有 \(1 \leq N \leq 10^5\)\(1 \le a_i \le 10^9\)

看到 \(n \le 10^5\),我们就要用归并排序或其他方法解决。虽然直接 sort 能过。

示例代码:

#include<bits/stdc++.h>
using namespace std; 
int n,a[100005];
int main(){
	scanf("%d",&n);
	for(int i=1; i<=n; i++){
		scanf("%d",&a[i]);
	}
	stable_sort(a+1,a+n+1);
	for(int i=1; i<=n; i++){
		printf("%d ",a[i]);
	}
	return 0;
}
posted on 2026-07-01 17:09  lz5332t  阅读(5)  评论(0)    收藏  举报