数据结构2-4 二叉堆


本文是对二叉堆以及STL中priority_queue的简单介绍。

二叉堆的基本概念

二叉堆是一种树状的堆,准确的说是一个完全二叉树构成的堆,并且在树根处的值是唯一的极值,其中在二叉堆中可以进行的数据操作是:
1.寻找并输出最大(最小)值
2.弹出最大(最小)值
3.插入新数值
在STL中优先队列的模型是建立在二叉堆的基础上的,所以通常使用优先队列来表示二叉堆。

二叉堆的模型

二叉堆通常会用数组直接模拟。

int heap[1<<N + 10];         //这里运用建树的方式直接建堆,同时令heap[1]为堆顶
int size = 1;                //size用来标记最后元素的位置

在这里插入图片描述

二叉堆的功能函数

二叉堆的输出

根据二叉堆的性质,堆顶(树根)处就时堆的极值。
代码如下:

int top(){
   return heap[1];
}

二叉堆的插入

二叉堆的插入首先需要满足完全二叉树,因而插入的位置必定是最小的叶子结点。
插入过程有顺序关系,我们不妨假设:
1.该堆是小顶堆。
2.元素3>元素1>新元素
在这里插入图片描述
由于元素3>新元素 因而交换其位置。
在这里插入图片描述
同上交换元素1与新元素位置。
在这里插入图片描述
这样就构成了新的堆。
代码实现如下:

void insert(int newelement){
    a[size] = newelement;
    int pos = size++;
    while(a[pos] >= a[pos>>1] ){
        swap(a[pos],a[pos>>1]);
        pos>>=1;
        if(pos == 1) break;
    }
}

二叉堆的删除

二叉堆的删除也需要将堆中极值从堆顶转移到叶子结点,然后删除叶子结点。
不妨假设:待删除元素>元素5>元素2>元素1
在这里插入图片描述
经过比较待删除元素的左右子结点,将元素1与待删除元素交换。
在这里插入图片描述
同理交换箭头所指两元素。由于交换后待删除元素已经到达叶子结点,于是直接删除。
在这里插入图片描述
这样新的二叉堆就完成了。
代码如下:

void pop(){
    int pos = 1;
    while(pos <= size){
        if(heap[pos<<1] > heap[pos<<1+1]){
            swap(heap[pos],heap[pos<<1+1]);
            pos = pos<<1+1;
        }
        else{
            swap(heap[pos<<1],heap[pos]);
            pos = pos<<1;
        }
    }
}

STL heap 与 priority_queue

C++ STL库中包含建堆用的heap库与二叉堆的priority_queue。
对于堆需要以下头文件

#include<heap>

对于优先队列需要以下头文件

#include<queue>

这里不赘述堆的操作,因为二叉堆只是堆中一部分,而优先队列与二叉堆切合度较高,所以只介绍优先队列的操作。

优先队列的构造

priority_queue<int,vector<int>,less<int> >  pq1;    //大顶堆
priority_queue<int,vector<int>,greater<int> >  pq2; //小顶堆

若使用结构体需要重载 < 运算符。

优先队列部分函数

功能函数名返回值类型
判断队列是否为空empty()bool
队列内元素数量size()int
元素进队push(int n)void
队首元素出队pop()void
显示队顶元素top()template T
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值