快速排序
归并排序也是基于分治法的。归并排序将待归并元素序列分为两个长度相等的子序列,为每一个子序列排序。然后再将他们合并成一个序列。合并两个子序列的过程称为两路归并。
编程经验:
1、快速解决问题法宝:1、最简单情况,画图分析,纸上执行;2、单步调试,快速查错。
2、程序顺便编译,所以后面函数中要用到前面函数的话,那个被依赖函数要先写。
/*
划分函数:
*/
void MergeSort(int *copy,int *orign,int start,int end) { if(start<end) //如果子序列的长度大于1 { int mid=(start+end)/2; //2路归并,漏写2 MergeSort(copy,orign,start,mid); //递归划分左子序列 MergeSort(copy,orign,mid+1,end); //递归划分右子序列 Merge(copy,orign,start,mid,end); //合并当前划分 } }
/*
排序函数:
1、需要一个copy数组存放每次划分后,左右子序列的元素,然后归并到原数组中。
*/
void Merge(int *copy,int *orign,int start,int middle,int end ) { //创建辅助数组 for(int i=start;i<=end;i++) copy[i]=orign[i]; //赋值左右归并后的数组到辅助数组 int wg1=start,wg2=middle+1,t=start; //分别用来监视左右子序列和归并后的数组序列 while(wg1<=middle&&wg2<=end) { //当其中的每个数组都还有元素时,则需要比较左右两个序列的彼此大小 if(copy[wg1]<copy[wg2]) orign[t++]=copy[wg1++]; else orign[t++]=copy[wg2++]; } //上述操作导致其中的某个子序列肯定被执行完,未执行完的子序列已经有序,只需要原样复制 while(wg1<=middle) orign[t++]=copy[wg1++]; while(wg2<=end) orign[t++]=copy[wg2++]; //如此就可归并当前划分的两个有序序列 }
主程序:
int _tmain(int argc, _TCHAR* argv[]) { //编程经验:递归树可帮助理解,从最简单情况辅助分析 //程序顺便编译,所以后面函数中要用到前面函数的话,那个被依赖函数要先写 //快速解决问题法宝:1、最简单情况,画图分析,纸上执行;2、单步调试,快速查错 int orgin[8]={21,25,49,16,17,8,31,41}; int copy[8]; //归并函数 void Merge(int *copy,int *orign,int start,int middle,int end ); //划分函数 void MergeSort(int *copy,int *orign,int start,int end); cout<<"----------------归并排序算法---------"<<endl; //测试 MergeSort(copy,orgin,0,7); //注意数组下标 for(int i=0;i<8;i++) cout<<orgin[i]<<" "; cout<<endl; return 0; }
测试结果:
----------------归并排序算法---------
8 16 17 21 25 31 41 49
请按任意键继续. . .