堆排序(完全二叉树)

堆排序,一种全新的排序方式,运用了完全二叉树存数据。

假设根是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;
}

 

posted @ 2020-02-14 20:27  zust-lms  阅读(535)  评论(0编辑  收藏  举报