堆排序(完全二叉树)
堆排序,一种全新的排序方式,运用了完全二叉树存数据。
假设根是u,那么左儿子就是u*2,右儿子是u*2+1.
用一维数组手撸一个堆排序。
1,如何插入一个数。heap[++size] = x; up(size);
2,求集合中的最小值。heap[1];
3,删除最小值。heap[1] = heap[size];size--;down(1);
4,删除任意值。heap[k] = heap[size];size--;down(k);up(k);
5,修改任意一个值。heap[k] = x; down(k);up(k);
那么堆基本性质是什么呢
小根堆。。也就是说每一个点都是小于等于他的左右儿子的,那么我们可以发现啊,他的根就是这个堆的最小值。
储存方式:数组1就是根节点,然后左右儿子往下遍历。
有俩个骚操作,down和up。。
down就是把1个节点往下移动,up就是把一个节点往上移动。
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n,m;
int h[N],cnt;
void down(int u)
{
int t = u;
if(u*2 <= cnt&&h[u*2]< h[t]) t=u*2;
if(u*2+1<= cnt && h[u*2+1] < h[t] ) t=u*2+1;
if(u!=t)
{
swap(h[u],h[t]);
down(t);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
cnt = n;
for(int i = n/2;i;i--) down(i);
while(m -- )
{
printf("%d ",h[1]);
h[1]=h[cnt--];
down(1);
}
puts("");
return 0;
}