1、快速排序
思想
通过一趟排序将数据分成两部分,一部分的数据值全部小于关键字,另一部分全部大于或者等于关键字,然后继续将这两部分进行同样操作,直到序列有序
图解
代码
两个函数
int Partition(int *a, int low, int high) {
int key = a[low];
while (low < high) {
while (low < high && a[high] >= key) {
high--;
}
a[low] = a[high];
while (low < high && a[low] <= key) {
low++;
}
a[high] = a[low];
}
a[low] = key;
return low;
}
void QuickSort(int *a, int low, int high) {
if (low < high) {
int key = Partition(a, low, high);
QuickSort(a, low, key - 1);
QuickSort(a, key + 1, high);
}
}
一个函数
void QuickSort(int *a, int low, int high) {
int l = low;
int h = high;
int key = a[low];
if (l >= h) return;
while (l < h) {
while (l < h && a[h] >= key) {
h--;
}
a[l] = a[h];
while (l < h && a[l] <= key) {
l++;
}
a[h] = a[l];
}
a[l] = key;
QuickSort(a, low, l - 1);
QuickSort(a, l + 1, high);
}
复杂度
时间复杂度:
最好: O ( n l o g n ) O(nlogn) O(nlogn)
最坏: O ( n 2 ) O(n^2) O(n2)
平均: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度:
最好: O ( n ) O(n) O(n)
最坏: O ( l o g n ) O(logn) O(logn)
稳定性
快速排序是不稳定的
2、归并排序
思想
归并排序使用的是分治思想,分就是将待排序序列分为若干个有序的子序列,合就是把有序的子序列合并为整体有序序列。
图解
代码
void Merge(int *a, int low, int mid, int high) {
int *b = new int[high - low + 1];
int i = low, j = mid + 1, k = low;
while (i <= mid && j <= high) {
b[k++] = a[i] < a[j] ? a[i++] : a[j++];
}
while (i <= mid) {
b[k++] = a[i++];
}
while (j <= high) {
b[k++] = a[j++];
}
for (i = low; i <= high; i++) {
a[i] = b[i];
}
delete[] b;
}
void MergeSort(int *a, int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
MergeSort(a, low, mid);
MergeSort(a, mid + 1, high);
Merge(a, low, mid, high);
}
}
复杂度
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( n ) O(n) O(n)
稳定性
归并排序是稳定的