归并算法的两种方法:
1、使用分治法的递归归并算法:
/*递归归并排序 *将有二个有序数列list[first...mid]和list[mid+1,...last]合并 *list:待排序数组 *first:子序列1的下界 *mid:子序列1的上界 *last:子序列2的上界 *temp:临时保存数组 */ void Merge(element list[], int first, int mid, int last, element temp[]) { int i = first, j = mid + 1; int m = mid, n = last; int k = 0; while (i <= m && j <= n) { if (list[i] < list[j]) temp[k++] = list[i++]; else temp[k++] = list[j++]; } while (i <= m) temp[k++] = list[i++]; while (j <= n) temp[k++] = list[j++]; for (i = 0; i < k; i++) list[first + i] = temp[i]; return ; } /*递归归并排序 *分治,完成递归归并 *list:待排序数组 *first:list下界 *last:list上界 *temp:临时保存数组 */ void mergesort(element list[], int first, int last, element temp[]) { if (first < last) { int mid = (first + last) / 2; mergesort(list, first, mid, temp); //左边有序 mergesort(list, mid + 1, last, temp); //右边有序 Merge(list, first, mid, last, temp); //再将二个有序数列合并 } return ; } /*递归归并排序 *list:待排序数组 *n:为数组长度 */ bool MergeSort(element list[], int n) { element *p = new element[n];//空间复杂度为O(n) if (p == NULL) exit(1); mergesort(list, 0, n - 1, p); delete[] p; return true; }
2、二路归并算法:
/*归并算法二,二路归并 *list:待排序数组 *n:为数组长度 *temp:临时保存数组 *k:为有序子数组的长度,一次二路归并排序后有序子序列存于temp数组中 */ void Merge2(element list[], int n, element temp[], int k) { int i, j; int m=0; int low1=0;//第一有序的下界 int up1, low2, up2;//第一有序的上界,第二有序的下界,第二有序的上界 /*将原始数组中足够分为两组的数据元素二路归并存放到数组temp中*/ while(low1+k < n-1) { low2 = low1+k; up1 = low2-1; up2 =(low2+k-1 < n-1) ? low2+k-1:n-1; for(i=low1, j=low2; i<=up1 && j <=up2; ) { if (list[i] <= list[j]) temp[m++] = list[i++]; else temp[m++] = list[j++]; } while (i <= up1) temp[m++] = list[i++]; while (j <= up2) temp[m++] = list[j++]; low1 = up2+1; } /*将原始数组中只够一组的数据元素顺序存放到数组temp中*/ i=low1; while(i<n) { temp[m++] = list[i++]; } return; } /*二路归并排序 *list:待排序数组 *n:为数组长度 */ bool MergeSort2(element list[], int n) { element *p = new element[n];//空间复杂度为O(n) if (p == NULL) exit(1); int k=1;//二路归并长度从1开始 int i=0; while(k<n) { Merge2(list, n, p, k);//每次归并后保存在p中 for(i=0; i<n; i++) list[i] = p[i];//从p中拷贝到list中 k *=2;//归并长度加倍 } delete[] p; return true; }