思路:
- 将待排序数组分成两个子数组,计算中间位置mid。
- 对左半部分进行递归排序,得到一个有序的子数组。
- 对右半部分进行递归排序,得到另一个有序的子数组。
- 合并两个有序的子数组,得到一个完整的有序数组。
示例图:
代码:
#include<iostream>
using namespace std;
void merge(int arr[], int start1, int end1, int start2, int end2){
//左边数组的长度
int n1 = start1 - end1 + 1;
//右边数组的长度
int n2 = start2 - end2 + 1;
//定义左右两个子数组
int* arr_left = new int[n1];
int* arr_right = new int[n1];
//从原数组中复制左边的数组
for(int i = 0; i < n1; i++) left_arr[i] = arr[start1 + i];
//从原数组中复制右边的数组
for(int i = 0; i < n2; i++) right_arr[i] = arr[start2 + i];
//指向左右两个数组首元素的指针
int left = 0, right = 0;
//临时数组,存放合并后的数组
int p = start1;
//左右两个数组不为空
while(left < n1 && right < n2){
//左边数组的元素小于右边数组的元素
if(arr_left[left] < arr_right[right]){
//将左边数组的值存入临时数组,同时两指针右移一位
arr[p++] = arr_left[left++];
}
//右边的数组为空
while(left < n1){
//将左边数组的值存入临时数组,同时两指针右移一位
arr[p++] = arr_left[left++];
}
//左边的数组为空
while(right < n2){
//将右边数组的值存入临时数组,同时两指针右移一位
arr[p++] = arr_right[right++];
}
}
mergesort(int arr[], int start, int end){
//当数组长度小于等于1时直接返回数组
if(start >= end){
return;
}
//取数组的中间位置
int mid = (start + end) / 2;
//对左边的数组进行递归排序
mergesort(arr, start, mid);
//对右边的数组进行递归排序
mergesort(arr,mid + 1, end);
//递归的的两个数组进行合并
merge(arr, start, mid, mid + 1, end);
}
int main(){
//定义数组
int arr[] = {8, 1, 3, 2, 9, 7, 6, 5, 4};
//数组长度
int n = sizeof(arr) / sizeof(arr[0]);
//调用递归数组
mergesort(arr, 0, n - 1);
//打印数组
for(int i = 0; i < n; i++){
cout << arr[i] << " ";
}
return 0;
}