归并排序的基本思想
1.基本思想(递归):
- 思路来源:两个有序序列,按序合并只需遍历一趟,效率较高;
- 归并排序:利用分-治-合的思想,先将待排序列划分为子序列,待子序列有序(元素个数为1)后,再将子序列两两合并,从而得到完整有序的序列。
2.算法步骤:
- 申请空间,分配一个与待排数组大小相同的数组;
- 利用递归函数,由中间位置不断划分序列,直到元素个数为1;(递去)
- 子序列按照升(降)序两两合并;(归来)
代码实现
#include <iostream>
#include <time.h>
#include <algorithm>
using namespace std;
/*排序方法类*/
class MySort {
public:
int n;
int* A;
//构造函数 ,便于挑选不同的排序方法
MySort(int N) {
this->n = N;
A = new int[this->n];
this->SetArray();
}
//随机初始化数组
void SetArray() {
srand(time(0));
for (int i = 0; i < n; i++) {
A[i] = rand() % 100 + 1;
}
}
//打印数组
void Print() {
for (int i = 0; i < n; i++) {
cout << A[i] << " ";
}
cout << endl;
}
//归并排序
void merge_sort(int *A, int n){
if (n < 2) return;
int *arrtmp = new int[n]; //分配一个与待排序数组大小相同的数组
_merge_sort(A, arrtmp, 0, n - 1); //调用递归函数进行排序
delete[] arrtmp;
}
void _merge_sort(int *A, int *arrtmp, int start, int end) {
if (start >= end) return; //递归终止条件(元素个数为1)
int mid = start + (end - start) / 2; //以下5行,将数组划分为2个子数组,分别继续递归
int start1 = start, end1 = mid;
int start2 = mid + 1, end2 = end;
_merge_sort(A, arrtmp, start1, end1);
_merge_sort(A, arrtmp, start2, end2);
int i = start; //已排序数组arrtmp计数器
while (start1 <= end1 && start2 <= end2) //升序合并两个子数组至arrtmp中
arrtmp[i++] = A[start1] < A[start2] ? A[start1++] : A[start2++];
while (start1 <= end1) arrtmp[i++] = A[start1++]; //剩余元素直接加入数组arrtmp尾部
while (start2 <= end2) arrtmp[i++] = A[start2++];
memcpy(A + start, arrtmp + start, (end - start + 1) * sizeof(int)); //将已排序数组arrtmp复制回到A中,排序完成
}
};
int main(){
//初始化数组
int N;
cout << "请输入数组长度:";
cin >> N;
MySort sort(N); //构造排序方法类
cout << endl;
cout << "获得"<<N<<"位随机数组:" ;
sort.Print();
sort.merge_sort(sort.A, N);
cout << "归并排序后:";
sort.Print();
cout << endl;
return 0;
}
代码验证:
适用说明
- 归并排序是建立在归并操作上的一种有效、稳定的排序算法,时间复杂度为O(nlogn),归并排序时需要和待排序记录个数相等的存储空间,所以空间复杂度为 O(n)。
- 归并排序适用于数据量大,并且对稳定性有要求的场景。