归并排序(分治思想)

来源:互联网 发布:怎样取消淘宝芝麻信用 编辑:程序博客网 时间:2024/06/07 00:41
  • 归并排序(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. 基本思想
    归并排序是用分治思想,分治模式在每一层递归上有三个步骤:
    分解(Divide):将n个元素分成个含n/2个元素的子序列。
    解决(Conquer):用合并排序法对两个子序列递归的排序。
    合并(Combine):合并两个已排序的子序列已得到排序结果。


动图演示:
这里写图片描述
具体的我们以一组无序数列{14,12,15,13,11,16}为例分解说明,如下图所示:
这里写图片描述
上图中首先把一个未排序的序列从中间分割成2部分,再把2部分分成4部分,依次分割下去,直到分割成一个一个的数据,再把这些数据两两归并到一起,使之有序,不停的归并,最后成为一个排好序的序列。


代码实现:

#include<iostream>using namespace std;void Merge_Sort(int a[],int b[],int left,int right);void merge(int origin[],int destin[],int left,int middle,int right);int main(){    int i,n;    int a[100],b[100];    cin>>n;    for(i=0;i<n;i++)        cin>>a[i];    Merge_Sort(a,b,0,n-1);    for(i=0;i<n-1;i++)        cout<<a[i]<<" ";    cout<<a[i]<<endl;    return 0;}//内部使用递归 void Merge_Sort(int a[],int b[],int left,int right){    int middle;    if(left<right)    {        middle = (left+right)/2;        Merge_Sort(a,b,left,middle);        Merge_Sort(a,b,middle+1,right);        merge(a,b,left,middle,right);     //合并到数组b     }}void merge(int origin[],int destin[],int left,int middle,int right){    int i=left,j=middle+1,k=left;    while(i<=middle&&j<=right)    {        if(origin[i]<origin[j])            destin[k++]=origin[i++];        else            destin[k++]=origin[j++];    }    //处理剩余元素     while(i<=middle)        destin[k++]=origin[i++];    while(j<=right)        destin[k++]=origin[j++];    for(k=left;k<=right;k++)        origin[k]=destin[k];}
原创粉丝点击