堆排序
/*
常见问题
1、堆排序是稳定排序?
No
2、堆排序最好最坏复杂度?
O(nlogn) O(nlogn)
3、堆排序Build操作复杂度?
O(n) //这个很容易答错,我当时面试答错还被要求手推过,Build是一个等比数列,最后算出来是O(n)的
4、前k大整数
找前k大/前k小整数的时候可以建一个大小为k的堆,时间复杂度O(nlogk),空间复杂度O(k)
*/
#include <iostream>
using namespace std;
int arr[101];
void PushDown(int a[], int now, int n) {
int lson = now<<1, rson = (now<<1)|1, maxx = now;
if(lson <= n && a[lson] > a[now]) maxx = lson;
if(rson <= n && a[rson] > a[maxx]) maxx = rson;
if(maxx != now) {
swap(a[now], a[maxx]);
PushDown(a, maxx, n);
}
}
void Build(int a[], int n) {
for(int i = n/2;i >= 1;i --) {
PushDown(a, i, n);
}
}
void HeapSort(int a[], int n) {
Build(a, n);
for (int i = n; i > 1; i--) {
swap(a[i], a[1]);
PushDown(a, 1, --n);
}
}
int main() {
int T = 10;
for(int i = 1;i <= T;i ++)
cin >> arr[i];
HeapSort(arr, 10);
for(int i = 1;i <= 10;i ++)
cout << arr[i] << " ";
cout << endl;
return 0;
}
快速排序
/*
常见问题
1、快速排序是稳定排序?
No
2、快速排序最好最坏复杂度,什么时候达到最坏复杂度?
O(nlogn) O(n^2) 原数列几乎有序的时候
3、快排平均为啥是O(nlogn)?
可以想象成一个矩形,每层Partition加起来肯定是n,高度由于QuickSort每次排序范围减半(平均),所以高度为logn,乘起来为O(nlogn)
4、有没有办法让快排最坏复杂度也是O(nlogn)?
在Partition的时候随机哨兵,而不是人为指定最后一个
*/
#include <iostream>
using namespace std;
int arr[101];
int Partition(int a[], int l, int r) {
int loc = l - 1;
for(int i = l;i < r;i ++) {
if(a[i] <= a[r]) {
swap(a[++loc], a[i]);
}
}
swap(a[++loc], a[r]);
return loc;
}
void QuickSort(int a[], int l, int r) {
if(l >= r) return;
int now = Partition(a, l, r);
QuickSort(a, l, now-1);
QuickSort(a, now+1, r);
}
int main() {
int T = 10;
for(int i = 1;i <= T;i ++)
cin >> arr[i];
QuickSort(arr, 1, 10);
for(int i = 1;i <= 10;i ++)
cout << arr[i] << " ";
cout << endl;
return 0;
}
前k小的数
/*
常见问题
1、复杂度是?为啥?
O(n),因为n+n/2+n/4+...是等比数列,算出来是O(n)
2、还有别的方法能解决这个问题吗?各自的优缺点?
堆排序也可以,堆排序节约空间O(k),快排变式需要O(n),但是堆排序时间复杂度为O(nlogk),快排变式只需要O(n)
*/
#include <iostream>
using namespace std;
int arr[101], k;
int Partition(int a[], int l, int r) {
int loc = l - 1;
for(int i = l;i < r;i ++) {
if(a[i] <= a[r]) {
swap(a[++loc], a[i]);
}
}
swap(a[++loc], a[r]);
return loc;
}
void QuickSort(int a[], int l, int r) {
if(l >= r) return;
int now = Partition(a, l, r);
if(now == k) return;
if(now > k) QuickSort(a, l, now-1);
else QuickSort(a, now+1, r);
}
int main() {
int T = 10;
cin >> k;
for(int i = 1;i <= T;i ++)
cin >> arr[i];
QuickSort(arr, 1, 10);
for(int i = 1;i <= T;i ++)
cout << arr[i] << " ";
cout << endl;
return 0;
}