分治递归的归并排序

1 篇文章 0 订阅
1 篇文章 0 订阅
本文介绍了分治法的概念,特别是如何通过递归方式解决复杂问题,以归并排序为例,详细阐述了其分、治、合三个步骤以及合并函数中的具体操作。
摘要由CSDN通过智能技术生成

分治递归

在求解一个输入规模为n,而n的取值又很大的问题时,直接求解往往非常困难。这时,可以先分析问题本身所具有的某些特性,然后从这些特性出发,把复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这种方法,就是所谓的分治法。而分成的小问题类型相同的话可以用递归来实现,这就是分治递归。

三个基本步骤:

分:把大问题分解成若干个小问题。

治:把分解后的小问题求解。

合:将各个小问题的解合并。

结合实例:

归并排序 :

就是将一个数字序列从中间分成两个长度差不多的子序列,之后又对两个子序列分别执行归并排序的算法,当两个子序列变为两个有序序列之后,再将两个有序的子序列合并成一个有序的序列。

分析:我们用mergesort函数来将数字序列分为两个子序列来排序,之后用merge函数来将两个子序列合并成一个有序序列。

在merge函数中

先用b[j]来存储要合并的两个子序列的总情况

之后用m1代表左边子序列长度,m2代表两个子序列总长度;

让i遍历左边子序列的情况,j遍历右边子序列的情况,然后比大小,哪边小就把哪边输入到a数组中,因为两个子序列是有序的,所以这样对比并输入a数组后,a数组就是两个有序子序列组合成的有序序列。

之后要保证两边的子序列都遍历完了,这样得到的合成的序列才是完整的。

最后一将其输出即可。

完整代码:

#include<iostream>

#include<stdio.h>

using namespace std;

int a[100]={};

void merge(int l,int mid,int r)

{

int k=l,i=l,j=1;

int b[100]={};

for(;i<=r;i++,j++)

{

   b[j]=a[i];

}

int m1=mid-l+1;

int m2=r-l+1;

i=1;

j=m1+1;

while(i<=m1&&j<=m2)

{

if(b[i]<=b[j])

{

a[k++]=b[i++];

}

else

{

a[k++]=b[j++];

}

}

while(i<=m1)

{

a[k++]=b[i++];

}

while(j<=m2)

{

a[k++]=b[j++];

}

}

void mergesort(int l,int r)

{

if(l==r) return;

int mid=(l+r)/2;

    mergesort(l,mid);

mergesort(mid+1,r);

merge(l,mid,r);

}

int main()

{

int i=1,j,m,k,l,r,n;

cout<<"请输入要排序的数字序列"<<endl;

while(1)

{

cin>>a[i++];

if(getchar()=='\n')

{

break;

}

}

l=1;

r=i-1;

    mergesort(l,r);

    cout<<"排序后的数字序列为"<<endl;

    for(i=1;i<=r;i++)

    {

     cout<<a[i]<<" ";

}

 }

运行结果:

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaojiwazi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值