归并排序(分治思想)

  • 归并排序(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];
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值