【问题标题】:Bi-Directional Binary Search Trees?双向二叉搜索树?
【发布时间】:2019-07-08 19:25:38
【问题描述】:

我已尝试实施 BST。到目前为止,它仅根据 BST 属性(左-下,右-大)添加键。虽然我以不同的方式实现它。

这就是我认为 BST 应该是的样子

Single Direction BST

我是如何实施 BST 的

Bi-Directional BST

问题是 BST 的实现是否正确? (我在双面 BST 中看到它的方式会更容易搜索、删除和插入)

import pdb; 
class Node:
    def __init__(self, value):
        self.value=value
        self.parent=None
        self.left_child=None
        self.right_child=None

class BST:

    def __init__(self,root=None):
        self.root=root

    def add(self,value):
        #pdb.set_trace()
        new_node=Node(value)
        self.tp=self.root                                                   
        if self.root is not None:                                         
                while True:
                    if self.tp.parent is None:
                        break
                    else:
                        self.tp=self.tp.parent
                                                                            #the self.tp varible always is at the first node.
                while True:
                    if new_node.value >= self.tp.value :

                        if self.tp.right_child is None:
                            new_node.parent=self.tp
                            self.tp.right_child=new_node
                            break
                        elif self.tp.right_child is not None:
                            self.tp=self.tp.right_child
                            print("Going Down Right")
                            print(new_node.value)
                    elif new_node.value < self.tp.value :
                        if self.tp.left_child is None:
                            new_node.parent=self.tp
                            self.tp.left_child=new_node
                            break
                        elif self.tp.left_child is not None:
                            self.tp=self.tp.left_child
                            print("Going Down Left")
                            print(new_node.value)
        self.root=new_node



newBST=BST()
newBST.add(9)
newBST.add(10)
newBST.add(2)
newBST.add(15)
newBST.add(14)
newBST.add(1)
newBST.add(3)

编辑:我使用了 while 循环而不是递归。有人可以详细说明为什么在这种特殊情况下和一般情况下使用 while 循环而不是递归是一个坏主意吗?

【问题讨论】:

  • 如果树是双向的,你认为根节点是什么?通常,根节点是没有父节点的节点,但如果树具有至少一条边,则可以没有这样的节点。
  • 在我的实现中,根节点的父节点为 NULL。在叶子的情况下也是如此。所有叶子的孩子也是NULL。我试图做的是将父节点与其子节点之间的所有连接保持为双向。虽然我明白你的意思。我认为,在您提到的情况下,数据结构看起来像一个圆圈而不是一棵树。我想顺时针和逆时针方向类似于 BST 中的左右方向。我说的对吗?
  • 你添加的是所谓的父指针。这允许人们通过向上然后向下找到下一个和上一个项目。而不是从树的顶部开始。它没有添加任何功能。只是改变了一些操作的复杂度。
  • 我有点困惑,它会如何增加操作的复杂性。我认为如果需要,可以完全忽略父指针。
  • 拥有父链接可以使一些操作更容易,因为您可以更轻松地从叶节点向上移动树。但是好处也有坏处,因为您需要在树结构发生变化时添加代码来更新这些链接。簿记工作最终可能与您在稍微更有效的遍历中节省的工作量相似。添加链接还不错,只是没有很大的好处。

标签: python python-3.x algorithm binary-search-tree


【解决方案1】:

偶尔会使用带有父链接的 BST。

好处不在于链接使搜索或更新更容易(实际上并非如此),而是您可以在任何给定节点之前或之后插入,或者从该节点向前或向后遍历,而无需搜索从根。

使用指向节点的指针来表示树中的位置而不是完整路径变得很方便,即使树包含重复项,并且该位置在其他地方执行更新或删除时仍然有效。

在抽象数据类型中,这些属性可以很容易地提供例如不会因突变而失效的迭代器。

【讨论】:

    【解决方案2】:

    您还没有描述如何使用父指针获得任何东西。关心回退到父节点的算法将通过爬回调用堆栈来实现。

    我去过那里——在我的数据结构类中,我用双向指针实现了我的东西。当我们谈到二叉树时,那些指针就不再有用了。正确使用递归取代了跟随链接备份树的需要。

    【讨论】:

    • 您可以通过“正确使用递归”解决很多问题,但不能解决所有问题。例如,考虑给定一个节点指针并要求返回父节点。如果没有父指针,您必须遍历树:O(log n) 操作。使用父指针,它是 O(1)。有了生产代码,我可以向您保证,差异很重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2012-07-15
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多