您的位置:首页 > 其它

归并排序(merge_sort)(及自底向上的归并排序)

2018-03-12 20:57 281 查看
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并过程为:比较a[i]和b[j]的大小,若a[i]≤b[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素b[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

分析过程:



将一个目标排序数组,采用二分法,一直递归分解,直到数量为1,开始两两比较排序合并,最终完成目标数组合并排序。

示例代码:

#include <bits/stdc++.h>

using namespace std;

void merge(int *a,int l,int mid,int r){
int temp[r-l+1];//临时存储数组,合并时使用
for(int i=l;i<=r;i++)
temp[i-l]=a[i];

int k0=l,k1=mid+1;
for(int k=l;k<=r;k++){
if(k0>mid){ //左边处理结束
a[k]=temp[k1-l];
k1++;
}
else if(k1>r){//右边处理结束
a[k]=temp[k0-l];
k0++;
}
else
4000
if(temp[k0-l]<=temp[k1-l]){//左边<右边
a[k]=temp[k0-l];
k0++;
}
else{//右边小于左边
a[k]=temp[k1-l];
k1++;
}
}
//  for(int i=l;i<=r;i++)
//      cout<<a[i]<<" ";
//  cout<<endl;

}

void merge_sort(int *a,int l,int r){

if(l>=r)    return; // 划分数组大小为1时返回
int mid=(l+r)/2;//取中间值
merge_sort(a,l,mid); //左边范围递归
merge_sort(a,mid+1,r);//右边范围递归

merge(a,l,mid,r);//合并排序
}

int main(){
int n;
cin>>n;
int arr
;
for(int i=0;i<n;i++){
cin>>arr[i];
}
merge_sort(arr,0,n-1);
for(int i=0;i<n;i++)
cout<<arr[i]<<" ";
return 0;
}


自底向上归并排序:



还有可以直接采用自底向上归并排序,不用递归。首先直接从相邻合并,步长依次成倍递增。

void merge_sort1(int *a,int n){
for(int sz=1;size<n;sz*=2) //步长成倍递增
for(int k=0;k<n-sz;i+=sz*2)//两两合并
merge(a,i,i+sz-1;min(i+2*sz-1,n-1));//使用min,防止右边界越界
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: