一、将长度为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
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;
}
如果有什么问题需要指正 欢迎在文章底下 友善 的留言 指正 一起进步一起成长。