堆排序(附单调队列)
前言
学生党,手写一下堆排序。
一、简单描述
(1)手写堆的向下维护操作。
(2)将原数组变成大根堆。
(3)实现堆排序(升序)。
(4)顺带实现单调队列。
二、堆排序代码
(1)实现堆的向下维护操作:
void down(int a[],int i,int len){
int fa = i, son_l = 2*fa+1, son_r = son_l+1;
if(son_l>=len) return;
while(a[fa]<a[son_l]||(son_r<len&&a[fa]<a[son_r])){
if(son_r>=len||a[son_l]>=a[son_r]){
swap(a[fa],a[son_l]);
fa = son_l;
}else{
swap(a[fa],a[son_r]);
fa = son_r;
}
son_l = 2*fa+1;
son_r = son_l+1;
if(son_l>=len) return;
}
}
(2) 将原数组整理为堆:
void heap(int a[],int len){
for(int i=len/2-1;i>=0;i--){
down(a,i,len);
}
}
(3)堆排序:
void heap_sort(int a[], int len){
heap(a, len);
for(int i=len-1;i>0;i--){
swap(a[i],a[0]);
down(a,0,i);
}
}
二、单调队列代码
(1)实现堆的向上维护操作
void up(int a[],int i,int len){
int son = i, fa = (son-1)/2;
if(son<=0) return;
while(a[son]>a[fa]){
swap(a[son],a[fa]);
son = fa;
fa = (son-1)/2;
if(son<=0) return;
}
}
(2)实现单调队列,大项在前(注:由于队列使用C++容器实现,上述代码需要稍作改动)
struct my_queue{
vector<int> heap;
int len = 0;
int top(){
return heap[0];
}
void pop(){
swap(heap[len-1],heap[0]);
heap.pop_back();
len--;
down(heap,0,len);
}
int push(int val){
heap.push_back(val);
len++;
up(heap,len-1,len);
}
};
欢迎大家交流~~