归并排序
- 时间复杂度:O(nlogn) (稳定)
归并排序体现了简单的分治法思想,思路如下
- 将数组均分为两组[left,mid],[mid+1,right]
- 对两组分别进行递归排序
- 合并两组数组为一组[left,right]
函数如下:
void mergeSort(int* a, int left, int right) {
if (left < right) {
int mid = (right + left ) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid + 1, right);
merge(a, left, mid, right);
}
}
- 归并排序的重点在于归并——将分开的两个数组进行合并,为此需要单独写一个合并函数merge
- merge函数思路:因为需要合并的两个数组left和right都是已经从小到大排好序的数组,所以只需要依次比对两个数组的剩余最小项,取小的那个项加入结果数组temp,然后对应的数组和temp数组的下标都++即可,直到left和right数组中的数全部加入到temp中。
代码如下:
void merge(int* a, int left, int mid, int right) {
int i = left; //指向数组1(left,mid)
int j = mid + 1; //指向数组2 (mid+1,right)
int* temp = new int[right - left + 1]; //保存结果的临时数组
int k = 0; //指向临时数组temp
while (i <= mid && j <= right) {
if (a[i] < a[j]) temp[k++] = a[i++];
else temp[k++] = a[j++];
}
while(i<=mid)
temp[k++] = a[i++];
while(j<=right)
temp[k++] = a[j++];
for (int i = 0; i < right-left+1; i++) {
a[left + i] = temp[i];
}
}
#include<iostream>
using namespace std;
void mergeSort(int* a, int right, int left);
void merge(int* a, int left, int mid, int right);
int main() {
int n;
cin >> n;
int* a;
a = new int[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
mergeSort(a, 0, n - 1);
for (int i = 0; i < n; i++) {
cout << a[i] << " ";
}
return 0;
}
//归并排序
void mergeSort(int* a, int left, int right) {
if (left < right) {
int mid = (right + left ) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid + 1, right);
merge(a, left, mid, right);
}
}
void merge(int* a, int left, int mid, int right) {
int i = left; //指向数组1(left,mid)
int j = mid + 1; //指向数组2 (mid+1,right)
int* temp = new int[right - left + 1]; //保存结果的临时数组
int k = 0; //指向临时数组temp
while (i <= mid && j <= right) {
if (a[i] < a[j]) temp[k++] = a[i++];
else temp[k++] = a[j++];
}
while(i<=mid)
temp[k++] = a[i++];
while(j<=right)
temp[k++] = a[j++];
for (int i = 0; i < right-left+1; i++) {
a[left + i] = temp[i];
}
}