小根堆

http://sjjp.tjuci.edu.cn/sjjg/datastructure/ds/web/paixu/paixu8.4.2.2.htm

 


堆(Heap)分为小根堆和大根堆两种,对于一个小根堆,它是具有如下特性的一棵完全二叉树: 
     (1)若树根结点存在左孩子,则根结点的值(或某个域的值)小于等于左孩子结点的值(或某个域的值); 
     (2)若树根结点存在右孩子,则根结点的值(或某个域的值)小于等于右孩子结点的值(或某个域的值); 
     (3)以左、右孩子为根的子树又各是一个堆。 
     大根堆的定义与上述类似,只要把小于等于改为大于等于就得到了。 
     由堆的定义可知,若一棵完全二叉树是堆,则该树中以每个结点为根的子树也都是一个堆。 
     分别为一个小根堆和一个大根堆。根据堆的定义可知,堆顶结点,即整个完全二叉树的根结点,对于小根堆来说具有最小值,对于大根堆来说具有最大值。是一个小根堆,堆中的最小值为堆顶结点的值1 8。是一个大根堆,堆中的最大值为堆顶结点的值74 Q若用堆来表示优先级队列,则堆顶结点具有最高的优先级,每次做删除操作只要删除堆顶结点即可。

小根堆

定义:堆的一种,即根节点小于它的左孩子,也小于它的右孩子.

小根椎的构建:  首先,将无序序列变成完全二叉树的形式.

排序 :               然后,从最后一个叶节点的父节点开始,往前逐个检查各个节点,看其是不是符合父节点小于它的子节点,如果不小于,则将它的 子节点中最小的那个节点与父节点对换;否则,不交换,继续往前检查.直到根节点为最小节点,然后将其与最后一个节点交换.此后,继续检查各个节点是不是满足最小根要求,如果不满足,则时行调整,直到所有的节点都满足,到此,第一轮调整结束.

                        下一步,将上一步得到的要节点与上次交换的节点的前一个节点交换,继续和上一步一样的调整.得到第二轮调整序列.

                        重复上两步,直到待调整的节点个数为1.

在最小堆里插入节点: 将要插入的节点X放在原来堆的完全二叉树的最后一个位置,然后不断地往上调整,直到X 调不动为止.


假设我们现在有两个集合,集合 1 存放当前数中较小的一半,集合 2 中存放当前数中较大的一半,如果集合中数的个数是奇数,那么把中位数单独列出来,记为mid。
我们记录集合 1 中的最大元素是 lmax , 集合 2 中的最小元素是 rmin
先看查询操作:如果集合有奇数个数,中位数就是 mid。如果集合有偶数个数,中位数等于(lmax+rmin)/2。
插入操作:分两种情况
(1).当前集合中有偶数个元素。
如果有 lmax <= x <= rmin,显然 mid=x 即可。
如果有 lmax > x , 显然 mid = lmax , 把 lmax 从集合 1 删除,x 插入集合 1
如果有 rmin < x , 显然 mid = rmin , 把 rmin 从集合 2 删除,x 插入集合 2 
(2).当前集合中有奇数数个元素 
如果 x >= mid ,那么把 mid 插入集合 1,x 插入集合 2 
如果 x < mid ,那么把 mid 插入集合 2,x 插入集合 1 
可以看到,上面的操作中涉及到对取出集合中的最大或最小元素,由于 n 很大,需要比较快的取得最大和最小数,因此需要堆来支持这些操作。把集合 1 设置成大根堆,集合 2 设置成小根堆,这样取元素,删除,插入的操作都是 logn,总的复杂度是 o(nlogn)


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值