Language agnostic 八字树插入

Language agnostic 八字树插入,language-agnostic,binary-tree,wikipedia,splay-tree,Language Agnostic,Binary Tree,Wikipedia,Splay Tree,通过一些练习来磨练我的二叉树技能,我决定实现一个splay树,如中所述 有一件事我不明白,那就是关于插入的部分 它说: 首先,我们在splay树中搜索x。如果x不存在,那么我们将找不到它,而是找到它的父节点y。其次,我们对y执行一个splay操作,它将y移动到splay树的根。第三,我们以适当的方式将新节点x作为根插入。这样,y要么是新根x的左子级,要么是右子级 我的问题是:与本文中的其他示例相比,上面的文本似乎过于简洁,这是为什么?这里似乎还有一些陷阱。例如,在将y节点展开到根节点之后,我不能

通过一些练习来磨练我的二叉树技能,我决定实现一个splay树,如中所述

有一件事我不明白,那就是关于插入的部分

它说:

首先,我们在splay树中搜索x。如果x不存在,那么我们将找不到它,而是找到它的父节点y。其次,我们对y执行一个splay操作,它将y移动到splay树的根。第三,我们以适当的方式将新节点x作为根插入。这样,y要么是新根x的左子级,要么是右子级

我的问题是:与本文中的其他示例相比,上面的文本似乎过于简洁,这是为什么?这里似乎还有一些陷阱。例如,在将y节点展开到根节点之后,我不能盲目地用x替换根节点,并将y作为左或右子节点固定到x上

让我们假设该值在树中不存在

我有一棵树:

           10
          /  \
         5    15
        / \    \
       1   6    20
我想插入8。根据上面的描述,我将查找6节点,在一个普通的二叉树中,8将被添加为6节点的右子节点,但是这里我首先必须将6节点展开到根节点:

            6
           / \
          5   10
         /     \
        1       15
                 \
                  20
那么这两者中的任何一个都显然是错误的:

          8                                  8
           \                                /
            6                              6
           / \                            / \
          5   10                         5   10
         /     \                        /     \
        1       15                     1       15
                 \                              \
                  20                             20

    6 is not greater than 8          10 is not less than 8
在我看来,首先进行展开,然后将新值正确添加为根的唯一方法意味着我必须检查以下条件(用于将展开的节点添加为新根的左子节点):

  • 向根倾斜的节点I小于新根(6<8)
  • 向根倾斜的节点I的最右边的子节点也小于新根(20 8)
  • 但是,如果我要拆分我展开的节点,通过获取正确的子节点并将其附加为新节点的正确子节点,我将得到以下结果:

                            8
                           / \
                          6   10
                         /     \
                        5       15
                       /         \
                      1           20
    
    但是,这个简单的改动总是能给我一棵正确的树吗?我很难想出一个例子,但这会导致以下情况:

    • 我要添加的新值高于临时根(我延伸到根的节点),但也高于临时根的右子节点的最左子节点
    一棵树在伸展后基本上看起来像这样,但在我替换根之前

                            10
                           /  \
                          5    15
                              /  \
                            11    20
    
    我想加上13,这将使新的树如下:

                            13
                           /  \
                         10    15
                         /    /  \
                        5   11    20  <-- 11, on the wrong side of 13
    
    13
    /  \
    10    15
    /    /  \
    5 11 20“Splay Tree”立刻让我想起了我不久前在CUJ上读到的一篇文章,你可能会在那里找到一些见解:

    第三,我们以适当的方式将新节点x作为根插入。这样,y要么是新根x的左子级,要么是右子级


    是的,但是这个新的根x必须有两个孩子,这就是为什么这个句子听起来可能会令人困惑。

    我不明白你所描述的问题是如何发生的。如果要在该树中插入13,首先必须找到它的位置:

                        10
                       /  \
                      5    15
                          /  \
                        11    20
    
    从10开始向右,从15开始向左,从11开始向右。。。然后你就没有更多的元素了。如果树上有13个孩子,我们会发现它是11岁的孩子。因此,根据规则,我们在11上执行一个splay操作,将11移动到splay树的根:

                        11
                       /  \
                      10   15
                     /       \
                    5         20
    
    然后我们添加13作为新根,11作为左子级:

                        13
                       /  \
                      11   15
                     /       \
                    10        20
                   /
                  5
    
    现在没有问题了

    首先,我们在splay树中搜索x。如果x不存在,那么我们将找不到它,而是找到它的父节点y。然后,我们添加新节点作为父节点的左或右子节点。第三,我们在添加的节点上执行一个splay操作,该操作将新值移动到splay树的根


    对我来说,这听起来也很有效,但如果我是你,我会尝试实现Wikipedia中描述的版本,因为很多人已经测试过,而且已经有很好的文档记录。

    新节点将像普通的二叉搜索树一样添加到树中。然后,新节点将向上展开,成为根节点或根节点的第一级节点。另外,当我们插入一个新节点时,我们需要找到放置它的位置,所以我们要进行查找。所有操作,包括在splay树上查找,都会触发splay操作。也许这就是为什么维基百科的文章这样描述它。我只是插入新节点并将其展开。无论哪种方式,这棵树都比以前更加平衡。很好

    呵呵,我只是看到你在我编辑后已经接受了一个答案:)“与文章中的其他示例相比,上面的文本似乎过于简洁,为什么呢?”所以。。。你的问题是为什么维基百科编辑不均?;)Wikipedia目前给出的insert指令是insert,然后是splay(而不是splay和insert),我认为这应该能提供更好的树平衡(平均)。这将产生一个稍微不同的树-