归并排序+一个编程需要注意的地方
2016-12-20 15:56
369 查看
概念:归并排序(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]。
代码如下:
过程:比较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数组的开始。这是一个很隐蔽的错误,而且不一步一步的调试还根本找不出来。以此为戒,谨记谨记。。。。。
相关文章推荐
- SharePoint中ListItem更新的一个需要注意的地方
- VC++编程需要注意的地方(请大家积极回复)
- 使用boost::asio需要注意的一个地方
- oracle 默认值需要注意的一个地方
- ios编程需要注意的地方
- Discuz中设置广告的一个需要注意的地方
- C++中方法定义和调用需要注意的一个地方
- 关于cin.ignore()函数的一个需要注意的地方
- c# 事务编程一些需要注意的地方
- C++中string的连续加法需要注意的一个地方
- VC++编程需要注意的地方(请大家积极回复)
- CreateIpForwardEntry函数在VIsta/win2008下需要注意的一个地方
- VC++编程需要注意的地方(请大家积极回复)
- (很乱)编程需要注意的地方,持续更新中...
- vc编写全局钩子需要注意的一个地方
- VC++编程需要注意的地方(请大家积极回复)
- SWT的GridData中一个需要注意的地方
- stsadm -o export 命令的一个需要注意的地方
- GDI编程需要注意的地方
- activity启动service需要注意的一个地方