理论基础 —— 堆

【堆的定义】

堆结构是具备以下性质的完全二叉树:

  • 小根堆:每个结点的值都小于或等于其左右孩子结点的值
  • 大根堆:每个结点的值都大于或等于其左右孩子结点的值

若将堆按照层序从 1 开始编号,则结点间满足下列关系:

  • 小根堆:\left\{\begin{matrix}k_i\leqslant k_{2i} \\ k_i\leqslant k_{2i+1} \end{matrix}\right.
  • 大根堆:\left\{\begin{matrix}k_i\geqslant k_{2i} \\ k_i\geqslant k_{2i+1} \end{matrix}\right.

从堆的定义可以看出,一个完全二叉树如果是堆,那么其根结点(堆顶)一定是当前堆中所有结点的最大值(大根堆)或最小值(小根堆),以层序结点编号为下标,将堆用顺序结构存储,那么堆对应于一组序列。

例如:

【堆的操作】

1.put 操作

put 操作,即向堆中加入一个元素,以大根堆为例,有:

  1. 在堆尾加入一个结点
  2. 将这个结点与其父结点进行比较:若其大于父结点,则将两者进行交换,否则操作结束
  3. 重复步骤 2,直到操作结束
int heap[N];
int size=0;
void put(int x){//heap[1]为堆顶
    heap[++size]=x;//在堆尾加入元素
    int now=size;//当前结点序号
    while(now>1){
        int next=now>>1;//该结点的父结点
        if(heap[now]<=heap[next])//当前结点值小于其父结点值 
            break;
        swap(heap[now],heap[next]);
        now=next;
    }
}

2.get操作

get 操作,即从堆中取出并删除堆顶元素,以小根堆为例,有:

  1. 令堆尾元素覆盖掉堆顶元素,并将其作为根结点 father,同时将堆的长度 -1
  2. 如果 father 有子结点,将根结点的子结点中最小的那个置为当前子结点的 son;若 father 没有子结点,结束操作
  3. 比较 father 与 son 的值,如果 father 的值小于或等于 son,结束操作;否则,交换这两个结点,并把 father 指向 son,重复步骤 2,直至操作结束
int heap[N];
int get(){//heap[1]为堆顶
    int now=1;//当前结点
    int res=heap[1];要删除的结点
    heap[1]=heap[size--];//堆长度-1
	while(now*2<=size){
        int next=now>>1;//当前结点的父结点
        if(next<size&&heap[next+1]<heap[next])//比较左右孩子,指向较大者
            next++;
        if(heap[now]<=heap[next])//当前结点值小于其父结点值,结束
            break;
        swap(heap[now],heap[next]);
        now=next;
    }
    return res;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值