归并排序+一个编程需要注意的地方

概念:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路 归并
过程:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
代码如下:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

void hebing(int cun[],int le1,int ri1,int p[],int le2,int ri2){
    int left1=le1,right1=ri1,left2=le2,right2=ri2;
    int ji=0;
while(left1<=right1&&left2<=right2)
{
    if(cun[left1]>cun[left2])p[ji++]=cun[left1++];
    else p[ji++]=cun[left2++];
}
while(left1<=right1)p[ji++]=cun[left1++];
while(left2<=right2)p[ji++]=cun[left2++];
for(int i=0;i<ji;i++)
    {cun[le1+i]=p[i];//一个已经被改变的值,不能再次使用,这也是为什么第一行要重复赋值的原因
    }
}

void MyMerge(int cun[],int left,int right,int p[]){

if(left<right)
{
    int mid=(left+right)/2;
    MyMerge(cun,left,mid,p);
    MyMerge(cun,mid+1,right,p);
    hebing(cun,left,mid,p,mid+1,right);
}
}

void Mergee(int cun[],int left,int right)
{
    int ao=right-left+10;
    int *p=new int[ao];
    MyMerge(cun,left,right,p);
    delete []p;
}


int main(){
    int cun[100];
    while(true){
            memset(cun,0,sizeof(cun));
    int n;
cout<<"请输入n的值:"<<endl;
cin>>n;
for(int i=0;i<n;i++)cun[i]=rand()%20;
cout<<"原来的序列:  ";
for(int i=0;i<n;i++)cout<<cun[i]<<" ";
cout<<endl;
Mergee(cun,0,n-1);
for(int i=0;i<n;i++)cout<<cun[i]<<" ";
cout<<endl;
}
return 0;}
注意点:一个变量在前面被改变值之后,在后面再次利用要注意他的值已经改变了。如上述代码中的left1,在给P数组赋值的时候,明明已经把left1++了,然后归并会cun数组的时候,还是以为left1是cun数组的开始。这是一个很隐蔽的错误,而且不一步一步的调试还根本找不出来。以此为戒,谨记谨记。。。。。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值