最大堆/最小堆、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;    //填坑
}

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
最小堆最大堆都是二叉树的一种特殊形式。最小堆是指每个节点的值都小于或等于其子节点的值,而最大堆则相反,每个节点的值都大于或等于其子节点的值。最小堆的删除操作是删除最小值,也就是删除根节点。具体的操作是将最后一个节点替换到根节点的位置,然后自顶向下递归调整以满足最小堆的要求。最大堆的删除操作是删除最大值,也是先将最后一个节点提到根节点的位置,然后删除最大值,并将新的根节点放到适当的位置。 最小堆最大堆的优势是可以在常数时间内访问最小或最大值,而使用数组则需要遍历查找最小或最大值,时间复杂度至少为O(n)。但是,维护最小或最大堆的结构需要额外的工作,这也带来了复杂度的花销。总的来说,最小堆最大堆是一种对数据进行快速查找的数据结构。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [图解二叉最小堆&最大堆)](https://blog.csdn.net/august5291/article/details/121120535)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [数据结构——最大堆最小堆](https://blog.csdn.net/qq_50675813/article/details/117753225)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值