小白学算法1.3——堆

小白学算法1.3——堆

标签: 小白学算法


1.什么是堆

堆是一种特殊的树形数据结构,每个结点都有一个值。通常我们所说的堆是指二叉堆。

当一棵二叉树的每个结点都大于等于它的两个子结点时,它被称为堆有序

根节点是堆有序的二叉树中最大的结点。

二叉堆(以下简称堆)是一组能够用堆有序的完全二叉树排序的元素,在数组中按照层级存储(一般不使用第一个位置),

  • 下图是一个堆有序的完全二叉树:
  • 堆一般用数组来存储其元素,因为索引方便快捷。由于一般不使用第一个位置,所以堆中元素起始下标为1,又因为二叉堆是完全二叉树,所以第k个结点的父结点为k/2,子结点为2k2k+1
  • 二叉堆从任意结点向下都能得到一个非递增的序列
  • 二叉堆从任意结点向上都能得到一个非递减的序列

2.堆的实现与算法

当一个堆插入、删除或者改变某个结点的时候,这个堆的有序状态就被打破了,从被打破的状态回到有序状态的过程叫做堆的有序化。堆的所以算法都是为了堆的有序化。

2.1堆的上浮算法

当堆的底部加入结点或者某个结点的值增大的时候,需要用到堆的上浮算法。

void swim(int* a, int k)
{
    while(k > 1 && a[k/2] < a[k])//a[k]是子结点并且大于父结点
    {
        swap(a, k/2, k);
        k = k/2;
    }
}

2.2堆的下沉算法

当堆的顶部加入结点或者结点的值减小的时候,需要用到堆的下沉算法。

void sink(int* a, int n, int k)
{
    while(2*k <= n)//k至少有一个子结点
    {
        int j = 2*k;
        if (j < n && a[j] < a[j+1]) j++;//如果有两个子结点,取较大者
        if (a[k] < a[j]) swap(a, k, j);//如果子结点大于父结点
        k = j;
    }
}

3.总结

  • 使用堆可以实现优先队列以及堆排序
  • 如果堆的结点从0开始,那么结点k的父结点为(k-1)/2,子结点为2k+12k+2
  • swim比较了一次,sink比较了两次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值