一、使用递归算法
递归算法的实质不难。分而治之,然后不断合并,最后形成一个整体。具体可以参考下面的图。
算法导论上采用的是递归算法。
1 void SelectSort::Merge(int p,int q,int k) //从0开始计数 2 { 3 4 int n1 = q-p+1; //左端数组大小 5 int n2 = k-q; //右端数组大小 6 int *L = new int[n1+1]; //开辟左端 7 int *R = new int[n2+1]; //开辟右端 8 for(int i=0;i<n1;i++) L[i] = SelectArry[p+i]; 9 for(int j=0;j<n2;j++) R[j] = SelectArry[q+1+j]; 10 L[n1] = INT_MAX; 11 R[n2] = INT_MAX; 12 int i=0; 13 int j=0; 14 for(int s = p; s <=k;s++) //s一定要小于等于k(为了与最后一个数做比较) 15 { 16 if(L[i] <=R[j]) {SelectArry[s] = L[i];i++;} 17 else {SelectArry[s] = R[j];j++;} 18 } 19 20 }
这个算法设置了一个小技巧,就是在第10、11行在左右数组中最后一个空间(每个L[]数组和R[]数组空间大小都比实际数组大小大1)设置为最大值。这个设置在for循环
中,利用if语句,比较大小时,可以将L[]或R[]区间中未比较的剩余元素自动在SelectArry数组进行填充。
1 void SelectSort::Merge_Sort(int p,int q) 2 { 3 if(p<q) 4 { 5 int r = (p+q)/2; 6 Merge_Sort(p,r); 7 Merge_Sort(r+1,q); 8 Merge(p,r,q); 9 } 10 }
进行递归调用,先左后右,到达底层后,再从分治到归并!
二、分治算法(非递归)
1 void SelectSort::Merge2(int index) 2 { 3 int i1 = 0; 4 int i2,j1,j2; 5 int i,j; 6 int k = 0 ; //用于ReplaceArry数组计数 7 while(i1+index<=int(SelectArry.size())-1) 8 { 9 j1 = i1+index; //第二个分组的起点 10 i2 = j1-1; //第一个分组的终点 11 j2 = (j1+index-1<=int(SelectArry.size())-1)? j1+index-1:SelectArry.size()-1; //第二个分组的终点 12 for(i=i1,j=j1;i<=i2&&j<=j2;k++) //两个有序字数组合并 13 { 14 if(SelectArry[i]<SelectArry[j]) {ReplaceArry[k] =SelectArry[i]; i++;} 15 else {ReplaceArry[k] = SelectArry[j];j++;} 16 } 17 while(i<=i2) //子数组2已经归并完毕,将子数组1剩余的元素存放到数组ReplaceArry数组中 18 { 19 ReplaceArry[k++] = SelectArry[i++]; 20 } 21 while(j<=j2) //子数组1已经归并完毕,将子数组2剩余的元素存放到数组ReplaceArry数组中 22 { 23 ReplaceArry[k++] = SelectArry[j++]; 24 } 25 i1 = j2+1; 26 } 27 for(i = i1;i<SelectArry.size();i++) ReplaceArry[k++] = SelectArry[i]; //将原始数组中只够一组的数据元素顺序存放到数组ReplaceArry数组中 28 }
非递归算法中,index代表一个数组中的元素数量大小。ReplaceArry数组用于存放按间距大小一轮比较交换完之后的数组。
1 void SelectSort::Merge_Sort2() 2 { 3 int i,k=1; 4 while(k<SelectArry.size()) 5 { 6 Merge2(k); //调用归并函数 7 for(i=0;i<SelectArry.size();i++) 8 SelectArry[i] = ReplaceArry[i]; //将元素从临时数组ReplaceArry放回数组SelectArry; 9 k = 2 * k; //归并长度加倍 10 } 11 }
由于是用类来写的,SelectArry、ReplaceArry数组封装在类中,其中SelectArry、ReplaceArry数组的定义是vector<int>;
转载请注明出处http://www.cnblogs.com/Su-30MKK/archive/2012/11/07/2759659.html