最大堆/最小堆、siftup和siftdown

从数据的 存储结构看,最大堆/最小堆是一个 数组
从数据的 逻辑结构看,最大堆/最小堆是一棵 完全二叉树

堆有以下三种基本操作:
1.初始化:将一个无序的序列初始化成堆。从最后一个非叶子结点(namely, (max_index-1)/2)开始,自右向左,自下向上,对每一个根结点执行siftdown操作。 O(N)
2.插入。在数组的末尾插入新的元素,然后执行siftup操作。 O(logN)
3.删除。删除指定位置的元素,用数组末尾的元素代替。然后视情况执行siftup或者siftdown操作(注意这两个操作是互斥的,只能执行其中之一)。 O(logN)

当前元素若可能与下一层元素交换,就是siftdown;若可能与上一层元素交换,就是siftup。 或者说当前元素被“挖出”后形成的“坑”,若往上升就是siftup,若往下降就是siftdown。

以下是siftup和siftdown的代码(以最小堆为例):
void siftup(int position)
{
    int child=position;
    int father=(child-1)/2;

    int temp=minheap[position];    //把要处理的元素“挖出来”,形成一个“坑”

    while(father>=0 && child>=1)
    {
        if(minheap[father]>temp)
        {
            minheap[child]=minheap[father];    //“坑”往上升

            child=father;    //更新下标
            father=(child-1)/2;
        }
        else
            break;
    }

    minheap[child]=temp;    //把temp填回“坑”里去
}

void siftdown(int position, int heapsize)
{
    int father=position;
    int child=father*2+1;

    int temp=minheap[position];    //仍然是挖坑

    while(child<heapsize)
    {
        if(child<heapsize-1 && minheap[child]>minheap[child+1])    //两个儿子较小的哪一个
            child=child+1;

        if(temp>minheap[child])
        {
            minheap[father]=minheap[child];    //坑往下沉

            father=child;    //更新下标
            child=2*father+1;
        }
        else
            break;    
    }

    minheap[father]=temp;    //填坑
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值