堆-数组实现

堆,利用完全二叉树的结构来维护一组数据。
满二叉树: 除最后一层无任何子节点外,每一层的所有结点都有两个子节点的二叉树。也就是说每层节点数都达到最大值。
完全二叉树: 最后一层的所有结点都连续集中在最左边。除此之外都是满的。

最大堆,就是root是这棵树最大的值。优先级队列。c++中包含头文件#include <queue> 后用priority_queue <T> s 来使用,默认最大堆。

堆的维护主要需掌握一下几个操作:

  1. pop。即删掉堆顶的操作,就把最后一个点放到堆顶,然后再往下面逐个比较,如果大的就交换位置
int Remove_Heap(HeapChain_idx H, int &e)
{
    if(H->sizee == 0)
        return 0;
    e = H->Element[1];
    H->Element[1] = H->Element[H->sizee--];    ///用最后一个数将堆顶覆盖
 
    int parent, child;
    for(parent = 1; parent * 2 <= H->sizee; parent = child)      ///将堆顶数往满足堆定义的位置移动
    {
        child = parent * 2;
        if(child < H->sizee && H->Element[child] < H->Element[child+1])      ///找出左右子节点的较大者
            child++;
 
        if(H->Element[parent] < H->Element[child])                           ///如果比子节点最大者小就往下移动
        {
            int t;
            t = H->Element[parent], H->Element[parent] = H->Element[child], H->Element[child] = t;
        }
        else                                                                  ///否则就比两个子节点都大或相等,满足堆定义。调整完成
            break;
    }
 
    return 1;
}
  1. push操作。插入的话,就比较大小,如果插入点比父节点大,那么就直接交换。操作时,可用父节点逐级向上交换值,直到找到插入点的位置
int In_Heap(HeapChain_idx H, int x)
{
    if(H->sizee >= H->capacity)
        return 0;
 
    int i = ++H->sizee;
    for( ; H->Element[i/2] < x; i /= 2)     ///插入的数只要比父节点大,父节点的值就往下移
        H->Element[i] = H->Element[i/2];
    H->Element[i] = x;
    return 1;
}
  1. 从数组中维护一个堆。即对所有父节点,采用维护操作即可。每次对父节点维护,可保证其子树维持堆性质。
int Adjust_Heap(HeapChain_idx H)
{
    if(H->sizee == 0)
        return 0;
 
    for(int k = H->sizee/2; k > 0; k--)             ///从最后一个节点的父节点调整使满足堆定义,调整至堆顶
    {
        int parent, child;
        for(parent = k; parent * 2 <= H->sizee; parent = child)   ///如果当前节点要比最大的子节点要小,就往下移,相等不用移动
        {
            child = parent * 2;
            if(child < H->sizee && H->Element[child] < H->Element[child+1])
                child++;
 
            if(H->Element[parent] < H->Element[child])
            {
                int t;
                t = H->Element[parent], H->Element[parent] = H->Element[child], H->Element[child] = t;
            }
            else
                break;
        }
    }
 
    return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值