//归并排序:逐层递归,把两个或多个有序序列合并成一个 (本文实现递增排序)
//m路归并,每选出一个元素需要对比关键字m-1次(本文采取二路归并)
//时间复杂度:O(nlog2n);空间复杂度:O(n)
//n个元素进行二路归并,归并的趟数即层数=log2n(向上取整)
#include <iostream>
#include <stdlib.h>
using namespace std;
//二路归并
//low:前部分数组首个元素 mid:前部分数组末尾元素 high:后部分数组末尾元素
void merge(int a[],int b[],int low,int mid,int high){
for(int i=low;i<=high;i++){
b[i]=a[i]; //将a中的待归并的元素备份
}
int i; //控制前一部分
int j; //控制后一部分
int k; //总控制
for(i=low,j=mid+1,k=low;i<=mid&&j<=high;k++){
//注意:这里是拿备份的元素进行对比,将结果放到我们起初的数组中
两个元素相等时,靠前元素(i控制)优先放入,保证稳定性
if(b[i]<=b[j]){
a[k]=b[i++];
}else{
a[k]=b[j++];
}
}
//注意上面for循环的结束条件,只剩下一个子表未合并,将该子表中剩余元素全部加到总表中
while(i<=mid){
a[k++]=b[i++];
}
while(j<=high){
a[k++]=b[j++];
}
}
//归并排序
void mergeSort(int a[],int b[],int low,int high){
//if判断是递归的结束条件,注意!
if(low<high){
//mid作为划分标准,即便只剩下两个元素,还是会把其拆分成左右两个部分
int mid=(low+high)/2;
//缩小范围,递归划分
mergeSort(a,b,low,mid);
mergeSort(a,b,mid+1,high);
//上面两个mergeSort函数实现了子列的有序
//merge函数将有序子列归并
merge(a,b,low,mid,high);
}
}
int main(){
int a[]={53,17,78,9,45,65,87,32,99,1};
int n=sizeof(a)/sizeof(int);
int *b=(int *)malloc(n*sizeof(int)); //创建一个和a相同大小的辅助数组
mergeSort(a,b,0,n-1);
//输出
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
return 0;
}
说明:本文为个人学习理解总结。