算法熟记-排序系列-归并排序
1. 简述
假设待排序数组为 int array[], 数组长度为n。归并排序是一个递归得方法。
当n==1时,停止递归。
当n>1时,开辟一个与array同样大小得数组,int tmp[]
将array[0]-array[n/2]得数组递归排序,将array[n/2+1]-array[n-1]的数组递归排序
将两部分数组,分别用两个指针,将小得元素一个一个放入到tmp数组中。
将tmp复制到array中,然后,释放tmp数组。
2. 复杂度
平均时间复杂度为O(N*LogN),空间复杂度为O(N)。
稳定性是稳定得排序,注意程序中,两个指针在比较得时候,如果大小相同,应该把第一个指针得数据放到tmp中,就能保证是稳定得排序了。
3. 代码
void merge_sort(int array[], int n) {
// 递归终止
if(n <= 1)
return;
// 递归排序
merge_sort(array, n/2);
merge_sort(array+n/2, n-n/2);
// 合并操作
int *tmp = new int[n];
int a = 0;
int b = n/2;
int i = 0;
while(a < n/2 && b<(n-n/2)) {
if(array[a] <= array[b]) // 这里得<=保证了稳定性
tmp[i++] = array[a++];
else
tmp[i++] = array[b++];
}
while(a < n/2) {
tmp[i++] = array[a++];
}
while(tmp[i++] = array[a++]) {
tmp[i++] = array[b++];
}
for(i=0; i<n; i++)
array[i] = tmp[i];
delete []tmp;
}
// 递归终止
if(n <= 1)
return;
// 递归排序
merge_sort(array, n/2);
merge_sort(array+n/2, n-n/2);
// 合并操作
int *tmp = new int[n];
int a = 0;
int b = n/2;
int i = 0;
while(a < n/2 && b<(n-n/2)) {
if(array[a] <= array[b]) // 这里得<=保证了稳定性
tmp[i++] = array[a++];
else
tmp[i++] = array[b++];
}
while(a < n/2) {
tmp[i++] = array[a++];
}
while(tmp[i++] = array[a++]) {
tmp[i++] = array[b++];
}
for(i=0; i<n; i++)
array[i] = tmp[i];
delete []tmp;
}
其中,最后得两个while和一个for语句中得复制,可以使用memcpy加快速度。
4. 参考资料
维基百科-归并排序 http://en.wikipedia.org/wiki/Merge_sort