字节面试考到的知识点,对输入整数数据流取中位数,面试当时想到了单调队列的方法,维护一个单调队列总的时间复杂度为,现场没撕出来,后来去leetcode提交最后一个测试案例超时
不过想法应该是对的,后来看答案是用堆的调整,复习下堆排序,
1.堆排序c++实现
1.1 准备
排序需要借助一个交换函数swap可以自己实现也可以用c++的实现
#include<bits/stdc++.h>
using namespace std;
void swap(int arr[], int a, int b){
int tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
return ;
}
1.2 堆的局部调整heapify
排序数组的长度为n,heapify将子结点较大的数移动到i的位置,最好的情况如果i为最大则则不需调整,最坏的情况一直调整到叶子结点调整的次数为树的高度,即
//时间复杂度为 O(logn) ,AdjustDown
void heapify(int arr[], int n, int i){
int c1 = 2 * i + 1; // 左结点
int c2 = 2 * i + 2; // 右结点
int max = i;
if(c1 < n && arr[c1] > arr[max]){
max = c1;
}
if(c2 < n && arr[c2] > arr[max]){
max = c2;
}
if(max != i){
swap(arr, i, max);
heapify(arr, n, max);
}
}
1.3 建堆
//时间复杂度为 O(logn)
void buildheap(int arr[], int n){
int l = (n - 1)/2; // 最后一个需要调整的结点位置
for(int i = l; i>=0 ;i--){
heapify(arr, n, i);
}
}
1.4 堆排序
将堆的第一个数和最后一个数交换,调整堆的长度减小1,
//时间复杂度为 O(nlogn)
void heapsort(int arr[], int n){
for(int i=n;i>0;i--){
swap(arr, 0, i-1);
buildheap(arr, i-1);
}
}
1.5 测试
int main(){
int arr[7] = {1,31,1,0,0,5,4};
cout<<"开始建堆"<<endl;
buildheap(arr, 7);
for(int i=0;i<7;i++){
cout<<arr[i]<<endl;
}
cout<<"开始排序"<<endl;
heapsort(arr, 7);
for(int i=0;i<7;i++){
cout<<arr[i]<<endl;
}
return 0;
}