归并排序-分治思想
递归做法
#include <iostream>
#include <vector>
using namespace std;
void mergeSortHelper(vector<int> &v, int start, int mid, int end, vector<int> &tmp) {
int i = start;
int j = mid + 1;
int k = start;
while(i <= mid && j <= end) {
if (v[i] <= v[j]) {
tmp[k] = v[i];
k++;
i++;
} else {
tmp[k] = v[j];
k++;
j++;
}
}
if(i <= mid) {
while(i <= mid) {
tmp[k] = v[i];
k++;
i++;
}
} else if(j <= end) {
while(j <= end) {
tmp[k] = v[j];
k++;
j++;
}
}
k = start;
while(k <= end) {
v[k] = tmp[k];
k++;
}
}
// 递归划分区间,划分到宽度为1时啥也不用做
// 划分到宽度为2时,使用 mergeSortHelper 排序
// 划分到宽度为4,
// ... ...
void mergeSort(vector<int> &v, int start, int end, vector<int> &tmp) {
if (start < end) {
int mid = (end + start)/2;
mergeSort(v, start, mid, tmp);
mergeSort(v, mid+1, end, tmp);
mergeSortHelper(v, start, mid, end, tmp);
}
}
void printVector(vector<int> &v) {
for(int i = 0; i < v.size(); i++) {
cout << v[i] << " ";
}
cout << endl;
}
void sort(vector<int> &v) {
int len = v.size();
vector<int> tmp(len);
mergeSort(v, 0, len-1, tmp);
}
int main()
{
vector<int> v = {1,6,9,2,6,3,7,9,0,2,4};
sort(v);
printVector(v);
return 0;
}
非递归做法
void mergeSort1(vector<int> &v) {
int len = v.size();
vector<int> tmp(len);
// 把长度为i(除了最后一截不能保证)的有序区间合并为长度为2*i(除了最后一截不能保证)的有序区间
for (int i = 1; i < len; i<<=1) {
int start = 0;
while(start < len) {
if (start + i*2 - 1 < len) {
mergeSortHelper(v, start, start+i-1, start + i*2 - 1, tmp);
start = start + i*2;
} else if (start + i - 1 < len) {
mergeSortHelper(v, start, start+i-1, len-1, tmp);
start = len;
} else {
start = len;
}
}
}
}
归并排序是稳定排序,能利用完全二叉树特性的排序一般性能都不会太差
每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为 logn
总的平均时间复杂度为O(nlogn)
归并排序的最好,最坏,平均时间复杂度均为O(nlogn)