繁体   English   中英

在python中删除二进制搜索树中的节点?

[英]Deleting nodes in a binary search tree in python?

所以我在我的计算机科学课上遇到一个问题,它要求我扩展我们以前编写的二进制搜索树类,并添加一种从树中删除节点的方法,如果该节点有这个必须考虑的话0,1或2个孩子。 在查看条件和内容后,我得出结论,我需要找到指定节点的父节点才能执行此操作,因为已删除节点的子节点将分配给父节点。 这就是我被困住的地方,因为我们刚刚开始使用节点和链表我还是比较新的,这就是为什么我不知道如何跟踪父节点。

这是BST类的代码:

进口副本

class _BSTNode:

    def __init__(self, value):
        """
        -------------------------------------------------------
        Creates a node containing a copy of value.
        Use: node = _BSTNode( value )
        -------------------------------------------------------
        Preconditions:
          value - data for the node (?)
        Postconditions:
          Initializes a BST node containing value. Child pointers are None, height is 1.
        -------------------------------------------------------
        """
        self._value = copy.deepcopy(value)
        self._left = None
        self._right = None
        self._height = 1
        return

    def _update_height(self):
        """
        -------------------------------------------------------
        Updates the height of the current node.
        Use: node._update_height()
        -------------------------------------------------------
        Postconditions:
          _height is 1 plus the maximum of the node's (up to) two children.
        -------------------------------------------------------
        """
        if self._left is None:
            left_height = 0
        else:
            left_height = self._left._height

        if self._right is None:
            right_height = 0
        else:
            right_height = self._right._height

        self._height = max(left_height, right_height) + 1
        return

    def __str__(self):
        """
        -------------------------------------------------------
        DEBUG: Prints node height and value.
        -------------------------------------------------------
        """
        return "h: {}, v: {}".format(self._height, self._value)

class BST:

    def __init__(self):
        """
        -------------------------------------------------------
        Initializes an empty BST.
        Use: bst = BST()
        -------------------------------------------------------
        Postconditions:
          Initializes an empty bst.
        -------------------------------------------------------
        """
        self._root = None
        self._count = 0
        return

    def is_empty(self):
        """
        -------------------------------------------------------
        Determines if bst is empty.
        Use: b = bst.is_empty()
        -------------------------------------------------------
        Postconditions:
          returns:
          True if bst is empty, False otherwise.
        -------------------------------------------------------
        """
        return self._root is None

    def __len__(self):
        """
        -------------------------------------------------------
        Returns the number of nodes in the BST.
        Use: n = len( bst )
        -------------------------------------------------------
        Postconditions:
          returns:
          the number of nodes in the BST.
        -------------------------------------------------------
        """
        return self._count

    def insert(self, value):
        """
        -------------------------------------------------------
        Inserts a copy of value into the bst.
        Use: b = bst.insert( value )
        -------------------------------------------------------
        Preconditions:
          value - data to be inserted into the bst (?)
        Postconditions:
          returns:
          inserted - True if value is inserted into the BST,
          False otherwise. Values may appear only once in a tree. (bool)
        -------------------------------------------------------
        """
        self._root, inserted = self._insert_aux(self._root, value)
        return inserted

    def _insert_aux(self, node, value):
        """
        -------------------------------------------------------
        Inserts a copy of _value into node.
        Private recursive operation called only by insert.
        Use: node, inserted = self._insert_aux( node, value )
        -------------------------------------------------------
        Preconditions:
          node - a bst node (_BSTNode)
          value - data to be inserted into the node (?)
        Postconditions:
          returns:
          node - the current node (_BSTNode)
          inserted - True if value is inserted into the BST,
          False otherwise. Values may appear only once in a tree. (boolean)
        -------------------------------------------------------
        """
        if node is None:
            # Base case: add a new node containing the value.
            node = _BSTNode(value)
            self._count += 1
            inserted = True
        elif value < node._value:
            # General case: check the left subtree.
            node._left, inserted = self._insert_aux(node._left, value)
        elif value > node._value:
            # General case: check the right subtree.
            node._right, inserted = self._insert_aux(node._right, value)
        else:
            # Base case: value is already in the BST.
            inserted = False

        if inserted:
            # Update the current node height if any of its children have been changed.
            node._update_height()
        return node, inserted

    def retrieve(self, key):
        """
        -------------------------------------------------------
        Retrieves a copy of a value matching key in a BST. (Iterative)
        Use: v = bst.retrieve( key )
        -------------------------------------------------------
        Preconditions:
          key - data to search for (?)
        Postconditions:
          returns:
          value - value in the node containing key, otherwise None (?)
        -------------------------------------------------------
        """
        node = self._root
        value = None

        while node is not None and value is None:

            if key < node._value:
                node = node._left
            elif key > node._value:
                node = node._right
            else:
                value = copy.deepcopy(node._value)
        return  value

    def inorder(self):
        """
        -------------------------------------------------------
        Prints the contents of the tree in inorder order.
        -------------------------------------------------------
        Postconditions:
          The contents of the tree are printed inorder.
        -------------------------------------------------------
        """
        if self._root is not None:
            self._inorder_aux(self._root)
        return

    def _inorder_aux(self, node):
        """
        -------------------------------------------------------
        Prints the contents of the subtree at node.
        -------------------------------------------------------
        Preconditions:
          node - a bst node (_BSTNode)
        Postconditions:
          prints:
          the values at the subtree of node in inorder
        -------------------------------------------------------
        """
        if node._left is not None:
            self._inorder_aux(node._left)
        print(node._value)
        if node._right is not None:
            self._inorder_aux(node._right)

        return

    def postorder(self):
        """
        -------------------------------------------------------
        Prints the contents of the tree in postorder order.
        -------------------------------------------------------
        Postconditions:
          The contents of the tree are printed postorder.
        -------------------------------------------------------
        """
        if self._root is not None:
            self._postorder_aux(self._root)
        return

    def _postorder_aux(self, node):
        """
        -------------------------------------------------------
        Prints the contents of the subtree at node.
        -------------------------------------------------------
        Preconditions:
          node - a bst node (_BSTNode)
        Postconditions:
          prints:
          the values at the subtree of node in postorder
        -------------------------------------------------------
        """
        if node._left is not None:
            self._preorder_aux(node._left)
        if node._right is not None:
            self._preorder_aux(node._right)
        print(node._value)


        return

    def preorder(self):
        """
        -------------------------------------------------------
        Prints the contents of the tree in preorder order.
        -------------------------------------------------------
        Postconditions:
          The contents of the tree are printed preorder.
        -------------------------------------------------------
        """
        if self._root is not None:
            self._preorder_aux(self._root)
        return

    def _preorder_aux(self, node):
        """
        -------------------------------------------------------
        Prints the contents of the subtree at node.
        -------------------------------------------------------
        Preconditions:
          node - a bst node (_BSTNode)
        Postconditions:
          prints:
          the values at the subtree of node in preorder
        -------------------------------------------------------
        """

        print(node._value)
        if node._left is not None:
            self._postorder_aux(node._left)
        if node._right is not None:
            self._postorder_aux(node._right)
        return


    def traverse(self):
        """
        ---------------------------------------------------------
        Returns the contents of bst in an array in sorted order.
        ---------------------------------------------------------
        Postconditions:
          returns:
          a - an array containing the contents of bst in sorted order.
        ---------------------------------------------------------
        """
        a = []
        self._traverse_aux(self._root, a)
        return a

    def _traverse_aux(self, node, a):
        """
        ---------------------------------------------------------
        Traverse the node's subtree in inorder, adding the contents of
        each node to an array
        ---------------------------------------------------------
        Preconditions:
          node - the root of a subtree (_BSTNode)
        Postconditions:
          a - contains the contents of the subtree of node 
                    in sorted order.
        ---------------------------------------------------------
        """
        if node._left is not None:
            self._traverse_aux(node._left, a)
        a.append(node._value)
        if node._right is not None:
            self._traverse_aux(node._right, a)


        return

    def is_identical(self, rhs):
        """
        ---------------------------------------------------------
        Determines whether two BSTs are identical.
        Use: b = bst.is_identical( rhs )
        -------------------------------------------------------
        Preconditions:
          rhs - another bst (BST)
        Postconditions:
          returns:
          identical - True if this bst contains the same values
          in the same order as rhs, otherwise returns False.
        -------------------------------------------------------
        """
        identical = self._is_identical_aux(self._root, rhs._root)
        return identical

    def _is_identical_aux(self, node1, node2):
        """
        ---------------------------------------------------------
        Determines whether two subtrees are identical.
        Use: b = bst.is_identical( node1, node2 )
        -------------------------------------------------------
        Preconditions:
          node1 - node of the current BST (_BSTNode)
          node2 - node of the rhs BST (_BSTNode)
        Postconditions:
          returns:
          result - True if this stubtree contains the same values as rhs
          subtree in the same order, otherwise returns False.
        -------------------------------------------------------
        """
        result = True
        if node1._value != node2._value:
            result = False
        if node1._left is not None and node2._left is not None and result == True:
            result = self._is_identical_aux(node1._left, node2._left)
        if node1.right is not None and node2._right is not None and result == True:
            result = self._is_identical_aux(node1._right, node2._right) 



        return result

    def leaf_count(self):
        """
        ---------------------------------------------------------
        Returns the number of leaves (nodes with no children) in bst.
        Use: n = bst.leaf_count()
        (Recursive algorithm)
        ---------------------------------------------------------
        Postconditions:
          returns:
          n - number of nodes with no children in bst.
        ---------------------------------------------------------
        """
        n = self._leaf_count_aux(self._root)
        return n

    def _leaf_count_aux(self, node):
        """
        ---------------------------------------------------------
        Returns the number of leaves (nodes with no children) in bst.
        Use: n = bst.leaf_count()
        (Recursive algorithm)
        ---------------------------------------------------------
        Preconditions:
          node - a BST node (_BSTNode)
        Postconditions:
          returns:
          n - number of nodes with no children below node.
        ---------------------------------------------------------
        """
        count = 0
        if node._left is None and node._right is None:
            count += 1
        if node._left is not None and node._right is None:
            count += self._leaf_count_aux(node._left)
        if node._left is None and node._right is not None:
            count += self._leaf_count_aux(node._right)
        if node._left is not None and node._right is not None:
            count += self._leaf_count_aux(node._left)
            count += self._leaf_count_aux(node._right)


        return count
    def _delete_node(self, node):
        """
        -------------------------------------------------------
        Removes a node from the bst.
        Use: node = self._delete_node(node)
        -------------------------------------------------------
        Preconditions:
          node - the bst node to be deleted (_BSTNode)
        Postconditions:
          returns:
          node - the node that replaces the deleted node. This node is the node
          with the maximum value in the current node's left subtree (_BSTNode)
        -------------------------------------------------------
        """

        # Your code here.

        return node

    def parent_i(self, key):
        """
        ---------------------------------------------------------
        Returns the value of the parent node of a key node in a bst.
        ---------------------------------------------------------
        Preconditions:
          key - a key value (?)
        Postconditions:
          returns:
          value - a copy of the value in a node that is the parent of the
          key node, None if the key is not found.
        ---------------------------------------------------------
        """

        # Your code here

        return value

BST类中的最后两个函数parent_i和_delete_node是我正在尝试编写的,注释是我的老师为我们需要编写的函数编写的条件。 我想如果我找到了获取父母的方法,那么删除功能应该很容易,但是现在我不知道从哪里开始。 非常感谢帮助! 中间的几个函数如min_i和max_i也应该是这样的,可能是我们班级的未来作业或实验室供我们编写。

提前致谢!

编辑:确定所以我现在理解了这个结构,但现在我很困惑,如果我尝试删除一个有2个孩子的节点,并且2个孩子中较高的一个也有2个孩子,依此类推? 我应该怎样做才能适用于所有尺码的所有款式?

  • 要确定节点的父节点,请将变量最初设置为None 现在,当您对节点进行二进制搜索时,将该变量设置为您之前使用的任何节点,一旦找到该节点,此变量应该为您提供父节点

  • 当您尝试删除节点时,如您所述,有3种情况。 只需用1个孩子替换已删除的节点,即可轻松解决前2个问题。 棘手的情况是你有2个孩子。 有两种方法可以解决这个问题,你可以用它的顺序替换那个节点,即它后面的节点(这个节点的右边孩子最左边的孩子),或者用它的前身替换它,即右边的节点在这之前(这个节点的左边孩子的最右边的孩子)。

  • 这只是实际发生的事情的快速浏览,但现在应该很明显,您不需要显式查找节点的父节点以删除该节点,只需跟踪上一个节点前往需要删除的节点就足够了。

有关详细信息,请参阅此示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM