从二进制最大堆中删除根节点的算法

时间:2013-11-24 19:08:29

标签: java algorithm binary-tree heap

我正坐在这里查看用于删除二进制最大堆中的根节点的算法,然后使用新根更新树。这是它的外观:

if (n==0) {
  empty = true;
} else {
  empty = false;
  top = a[1];
  a[1] = a[n];
  n = n-1;
  parent = 1;
  child = 2;

  while (child<=n-1) {
    if (tab[child]<tab[child+1]){
      child = child+1;
    }
    if (tab[child]>tab[parent]) {
      swap[tab[child],tab[parent]);
      parent=child;
      child=parent*2;
    } else {
      child=n;
    }
  }
}

所以,我不明白为什么它说:

while(child<=n-1)

我的意思是,假设我们有一个包含11个节点的堆,包括根节点。当我们删除根节点时,我们剩下10个节点。根据此代码,如果child = 10,循环应该停止。但这有什么意义呢?即使child = 10parent = 5,它仍然运行if,以查看是否child > parent?为什么不检查那种情况,而是停止循环?

希望这是有道理的。对不起,如果很明显,我一整天都在看堆和节点,我的脑袋不再合作。

2 个答案:

答案 0 :(得分:3)

您必须检查两个子节点。从二进制最大堆中删除的规则是:

  1. 结果是堆顶部的节点(即根)。
  2. 将项目从堆末尾移动到堆顶部。
  3. 当您插入的项目小于其子项目时,请将其与最大的子项交换。
  4. 您的代码未正确执行第3步。首先要确定哪个是最大的孩子。

    我怀疑代码正在使用(child <= n-1),因为它假设您将检查childchild+1上的项目,以满足第3步的要求。

    在帖子被修改后添加

    我认为(child <= n-1)是一个错误。它应该是:

    while (child <= n)
    {
        if (child < n && tab[child] < tab[child+1])
        {
            child = child+1;
        }
    

    否则,正如您所说,有可能无法进行比较。

答案 1 :(得分:1)

不要忘记child只是存储二进制堆的数组的索引。这意味着如果您到达n元素,则可以停止,因为最后一个元素已从树中删除。

您绝不会将childparent进行比较,而应将tab[child]tab[parent]进行比较!