TreeMap如何搜索给定条目的后继者?

时间:2013-08-05 16:46:20

标签: java algorithm treemap

我对java.util.TreeMap:

的以下方法感到有些困惑
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
        if (t == null)
            return null;
        else if (t.right != null) {
            Entry<K,V> p = t.right;
            while (p.left != null)
                p = p.left;
            return p;
        } else {
            Entry<K,V> p = t.parent;
            Entry<K,V> ch = t;
            while (p != null && ch == p.right) {
                ch = p;
                p = p.parent;
            }
            return p;
        }
    }

此方法用于TreeMap的 containsValue 方法。它被告知要检索第一个Entry的后继者和先前检索的后继者的继承者,依此类推。 所以上面的方法检索整个TreeMap的条目。 但我不太了解它是如何运作的,它如何寻求继任者?

谢谢!

3 个答案:

答案 0 :(得分:3)

这适用于二叉搜索树,它使用以下事实:

  1. 子树中的'leftest'叶子表示最小的密钥。
  2. 父元素总是大于其左子树的任何节点(二元搜索树的定义)。
  3. 所以,这正是算法正在做的事情:

    1. 它搜索是否有正确的子树,如果有,则最左边的叶子有成功者,因为它是比给定节点大的最小值。
    2. 如果没有正确的子树,则意味着后继者不在t是其根的子树中,因此它搜索t是节点的第一个父节点在它的左子树中。
    3. 示例:

                 4
                / \
               /   \ 
              /     \
             /       \
            2         6
           /         / \
          /         /   \
         1         5     7
      
      • 2的继承者:因为2没有正确的子树,所以它是第一个父树 2在左子树中,即4 - 正如预期的那样(代码中的else个案例。)
      • 4的继承者是右子树的“最左边的叶子”,按预期为5。

      此外,作为“测验”,请确保您了解p != null中的条件while (p != null && ch == p.right)何时不符合。

答案 1 :(得分:2)

这种方法背后的逻辑如下:

  • null节点的后继者不存在
  • 具有右子树的任何节点的后继者是其右子树的最左边的叶子节点(即“向右走,然后尽量向左走,向左走;这将是继承者。”
  • 没有右子树的任何节点的后继者是其第一个祖先节点,当前节点位于左子树中。

这个逻辑在条件链的三个分支中表示:第一个if处理null,第二个遍历右分支的左子树,其else步行查找祖先的树结构,使当前子树在其左侧。

以下是算法需要查找后继时搜索的样子,并且存在正确的子树:当前节点显示为红色,后续节点显示为绿色。该算法向右一步,然后一直向左进行。

Right subtree

以下是算法需要查找后继时搜索的外观,但没有正确的子树:当前节点显示为红色,后续节点显示为绿色。算法上升,检查我们是否来自左子树。对于当前节点的父节点,答案是“否”,因为当前节点位于右子树中。对于父级的父级,答案为“是”,因此它将作为当前节点的后继者返回。

Left subtree

答案 2 :(得分:0)

TreeMap 内部使用红黑树数据结构,任何红黑树都必须是二叉搜索树。

寻找后继者的概念就像寻找下一个合适的元素/对象/节点。

如果我们仔细查看 Amit 的示例并对其节点进行排序,那么它们将是:

1,2,4,5,6,7

现在,如果我们打算为 4 找到后继者,那就是 5,这样更容易理解。现在,请注意 Amit 提到的点 右子树的“最左边的叶子”

类似地,在 2 的情况下,它将是 4。用 Amit 的第一个条件映射它 因为 2 没有右子树,它的第一个父节点 2 在左子树中

参考:
红黑树 |红黑树介绍 |数据结构 https://www.youtube.com/channel/UCM-yUTYGmrNvKOCcAl21g3w

首先了解实际底层数据结构的一些非常好的参考!