归并排序
- 确定分界点 mid = (left+ right)/2
- 递归排序 left right
- 归并—合二为一
例子:
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1000010;
static int q[N], tmp[N];
// tmp是额外的辅助数组,用来储存排好的数据
// l = 0 r = n-1
void mergesort(int q[], int l, int r)
{
// mid是左半边的边界,mid+1是右半边的边界
if (l >= r) return;
int mid = l + r >> 1; //定义分界点
mergesort(q, l, mid);
mergesort(q, mid + 1, r); //递归排左右边
// k表示已经合并 了多少个数,i是指向数组左半边的起点指针
// j 是指向数组右半边的起点指针
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
{
if (q[i] <= q[j])
{
tmp[k++] = q[i++]; //如果数组左边的值小于右边的值,就把左边的值存入tmp数组中
}
else
{
tmp[k++] = q[j++]; //反之,如果数组左边的值大于右边的值,就把右边的值存入tmp数组中
}
}
while (i <= mid)
{
tmp[k++] = q[i++];
}; //如果左半边没有排完,就把左边剩下的值直接放入tmp数组中
while (j <= r)
{
tmp[k++] = q[j++];
};//如果右半边没有排完,就把右边剩下的值直接放入tmp数组中
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
int main(void)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &q[i]);
}
mergesort(q, 0, n - 1);
for (int i = 0; i < n; i++)
{
printf("%d ", tmp[i]);
}
return 0;
}