快排和归并的区别
1.分界点不同
快排是从中选取一个数做分界点
归并是选择中间位置作为分界点
2.是否稳定
快排是不稳定的算法
归并是稳定的算法
所谓稳定不稳定是说,两个相同的数在排序完相对位置是否改变了,不改变就是稳定,改变就是不稳定
归并基本思想
1.确定分界点
mid = (l + r ) / 2
2.递归排序left,right
化为两个有序的序列
3.两个序列合二为一
设两个序列的起始点 i 和 j , i = l, j = mid + 1
循环终止边界条件是i = mid , j = r
再用一个数组把两个序列合二为一
模板代码
void merge_sort(int q[],int l, int r)
{
if(l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid),merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while(i <= mid && j <= r)
if(q[i] <= q[j]) tmp[k ++] = q[i ++];
else tmp[k ++] = q[j ++];
while(i <= mid) tmp[k ++] = q[i ++];
while(j <= r) tmp[k ++] = q[j ++];
for(i = l,j = 0;i <= r;i ++,j ++) q[i] = tmp[j];
}
练习题目
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int n,q[N],tmp[N];
void merge_sort(int q[],int l, int r)
{
//说明当序列不存在或者只有一个时退出
if(l >= r) return;
int mid = l + r >> 1;
//将两个序列有序排序
merge_sort(q, l, mid),merge_sort(q, mid + 1, r);
//合并两个有序序列
//k为第三个数组里存了几个数
int k = 0, i = l, j = mid + 1;
while(i <= mid && j <= r)
if(q[i] <= q[j]) tmp[k ++] = q[i ++];
else tmp[k ++] = q[j ++];
while(i <= mid) tmp[k ++] = q[i ++];
while(j <= r) tmp[k ++] = q[j ++];
for(i = l,j = 0 ; i <= r ; i ++, j ++) q[i] = tmp[j];
}
int main()
{
scanf("%d", &n);
for(int i = 0;i < n; i ++) scanf("%d", &q[i]);
merge_sort(q, 0, n-1);
for(int i = 0;i < n; i ++) printf("%d ", q[i]);
return 0;
}