赞
踩
一、将长度为n序列 递归拆解成n/2 个子序列 进行两两排序(递归归并左边的子序列,递归归并右边的子序列) 直到得到n个长度为1的自然有序序列为止
二、将两个已排序的子序列进行排序合并 直到有序序列的的长度为n 结束
三、图解如下:
/**
*功能:拆分有序的序列两两排序-拆解结束的条件 子序列长度为1的时候
*/
void sortArr(int arr[], int low, int hight) {
if (low < hight) {
int mid = (hight + low) / 2;
sortArr(arr,low,mid);// 递归拆解左边的序列
sortArr(arr, mid + 1, hight);// 递归拆解左边的序列
mergeArr(arr, low, mid, hight);// 将两个有序的子序列(arr[low至mid]、arr[mid+1至hight] 排序合并成一个新的有序列
}
}
实际上当他们拆分成1个有序的子序列的时候才开始调用mergeArr 进行排序 合并 然后得到新的有序的序列(长度为2)然后返回上一层得再进行排序
- int i = low, j = mid + 1, k = 0; while (i <= mid && j <= hight) { if (arr[i] < arr[j]) { tempArr[k] = arr[i]; i++; } else { tempArr[k] = arr[j]; j++; } k++; } // 如果 arr[low] 到 arr[mid] 区间中的数组还没有比较完成 ,直接复制到tempArr 中 while (i <= mid) { tempArr[k] = arr[i]; i++; k++; } // 如果 arr[mid+1] 到 arr[hight] 区间中的数组还没有比较完成 ,直接复制到tempArr 中 while (j <= hight) { tempArr[k] = arr[j]; j++; k++; }
void mergeArr(int arr[], int low, int mid, int hight) { int* tempArr = new int[hight - low + 1]; int i = low, j = mid + 1, k = 0; while (i <= mid && j <= hight) { if (arr[i] < arr[j]) { tempArr[k] = arr[i]; i++; } else { tempArr[k] = arr[j]; j++; } k++; } // 如果 arr[low] 到 arr[mid] 区间中的数组还没有比较完成 ,直接复制到tempArr 中 while (i <= mid) { tempArr[k] = arr[i]; i++; k++; } // 如果 arr[mid+1] 到 arr[hight] 区间中的数组还没有比较完成 ,直接复制到tempArr 中 while (j <= hight) { tempArr[k] = arr[j]; j++; k++; } // 比较完成之后 将原本的数组arr 下标 low-hight 对应的内容 进行改变 i = low; for (int tempK = 0;((tempK < k)&&(i<=hight));tempK++) { arr[i] = tempArr[tempK]; i++; } delete[] tempArr; tempArr = NULL; }
归并代码实际上就是两两个拆分 拆分到单个之后 再逐级排序合并 他的算法的空间复杂度为On 时间复杂度为nlog2n
#include <iostream> using namespace std; /** *功能:将两个有序的数组合并成一个整体有序的数组 */ void mergeArr(int arr[], int low, int mid, int hight) { int* tempArr = new int[hight - low + 1]; int i = low, j = mid + 1, k = 0; while (i <= mid && j <= hight) { if (arr[i] < arr[j]) { tempArr[k] = arr[i]; i++; } else { tempArr[k] = arr[j]; j++; } k++; } // 如果 arr[low] 到 arr[mid] 区间中的数组还没有比较完成 ,直接复制到tempArr 中 while (i <= mid) { tempArr[k] = arr[i]; i++; k++; } // 如果 arr[mid+1] 到 arr[hight] 区间中的数组还没有比较完成 ,直接复制到tempArr 中 while (j <= hight) { tempArr[k] = arr[j]; j++; k++; } // 比较完成之后 将原本的数组arr 下标 low-hight 对应的内容 进行改变 i = low; for (int tempK = 0;((tempK < k)&&(i<=hight));tempK++) { arr[i] = tempArr[tempK]; i++; } delete[] tempArr; tempArr = NULL; } /** *功能:拆分有序的序列两两排序-拆解结束的条件 子序列长度为1的时候 */ void sortArr(int arr[], int low, int hight) { if (low < hight) { int mid = (hight + low) / 2; sortArr(arr,low,mid);// 递归拆解左边的序列 sortArr(arr, mid + 1, hight);// 递归拆解左边的序列 mergeArr(arr, low, mid, hight);// 将两个有序的子序列(arr[low至mid]、arr[mid+1至hight] 排序合并成一个新的有序列 } } int main() { int arr[] = {5,4,6,3,1,2,8,7,10}; cout << "before sort " << endl; for (int j = 0;j < 9;j++) { cout << arr[j] << " "; } sortArr(arr,0,8); cout << endl << "after sort " << endl; for (int j = 0;j <9;j++) { cout << arr[j] << " "; } return 0; }
如果有什么问题需要指正 欢迎在文章底下 友善 的留言 指正 一起进步一起成长。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。