堆有序或二叉堆的两个性质

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

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

堆的表示
img

命题 O:根结点是堆有序的二叉树中的最大结点。

由堆有序的定义可知,层数为 2 的堆有序二叉树满足命题。

假设存在层数等于 m 的堆有序二叉树使得命题成立,那么,对于层数为 m+1 的堆有序二叉树:

该二叉树由两颗层数为 m 的堆有序二叉树及一个根节点组成,因为层数等于 m 的堆有序二叉树满足命题,故两棵子二叉树的根结点为子树中的最大结点,同时由堆有序的定义知这两棵子二叉树的根节点小于等于总树的根节点,故有层数为 m+1 的堆有序二叉树满足命题。

由数学归纳法,对于任意堆有序的二叉树,命题 O 总成立。

命题 P:在一个二叉堆中,位置(数组索引)k 处的结点的父结点的位置为 ⌊k/2⌋,而它的两个子结点的位置则分别为 2k 和 2k+1。

用以下结构分别表示二叉堆数组中任意的父节点(结点 A)、子结点(左子结点 B 和右子结点 C):

    /
   〇 A
  /  \
 〇 B 〇 C
/  \ /  \

设结点 A 所在深度为 k(根结点所在深度为 0),所在列为 j(每层的最左侧结点的列号为 0)、S_p(k) 为深度为 k 的完美二叉树的结点总数。

则 A 结点在二叉堆数组中的索引 I(A)=S_p(k-1)+j+1=2^k-1+j+1=2^k+j[1],B 的索引 I(B)=S_p(k)+2j+1=2^{k+1}+2j[2],C 的索引 I(C)=I(B)+1=2^{k+1}+2j+1。

I(B)=2I(A),I(C)=2I(A)+1,I(A)=⌊I(B)/2⌋=⌊I(C)/2⌋。命题成立。

使用数组的第一个位置(索引 0)时,I(A)=S_p(k-1)-1+j+1=2^k-1-1+j+1=2^k+j-1,I(B)=S_p(k)-1+2j+1=2^{k+1}+2j-1,I(C)=I(B)+1=2^{k+1}+2j。

I(B)=2I(A)+1,I(C)=2I(A)+2,I(A)=⌊(I(B)-1)/2⌋=⌊(I(C)-1)/2⌋。

类似不难得到多叉堆的相关命题,比如三叉堆(不使用数组的第一个位置)有:

位置(数组索引)k 处的结点的父结点的位置为 ⌊(k+1)/3⌋,而它的三个子结点的位置则分别为 3k-1、3k 和 3k+1。

      /
     〇 A 
  /  |   \
〇 B 〇 C 〇 D

设结点 A 所在深度为 k(根结点所在深度为 0),所在列为 j(每层的最左侧结点的列号为 0)、S_{tp}(k) 为深度为 k 的完美三叉树的结点总数。

则 A 结点在三叉堆数组中的索引 I(A)=S_{tp}(k-1)+j+1=(3^k-1)/2+j+1[3],B 的索引 I(B)=S_{tp}(k)+3j+1=(3^{k+1}-1)/2+3j+1[4],C 的索引 I(C)=I(B)+1=(3^{k+1}-1)/2+3j+2,D 的索引 I(D)=I(B)+2=(3^{k+1}-1)/2+3j+3。

I(B)=3I(A)-1,I(C)=3I(A),I(D)=3I(A)+1,I(A)=⌊(I(B)+1)/3⌋=⌊(I(C)+1)/3⌋=⌊(I(D)+1)/3⌋。命题成立。

图片来自《算法(第四版)》


  1. S_p(k)=2^{k+1}-1 ↩︎

  2. 与结点 A 处在同一层且位于 A 之前的结点总数为 j,则与结点 B 处在同一层且位于 B 之前的结点总数为 2j。 ↩︎

  3. S_{tp}(k)=(3^{k+1}-1)/2 ↩︎

  4. 与结点 A 处在同一层且位于 A 之前的结点总数为 j,则与结点 B 处在同一层且位于 B 之前的结点总数为 3j。 ↩︎

posted @ 2022-03-24 21:01  Higurashi-kagome  阅读(99)  评论(0编辑  收藏  举报