当前位置: 首页 > 知识库问答 >
问题:

删除二进制搜索树

席成仁
2023-03-14

我试着删除二叉查找树的节点,当我打印出来的时候,我得到的结果实际上不是这个删除,实际上可以删除二叉树本身的任何键。

我是二进制搜索树的新手。有人能帮我写代码吗?我们将感谢您的帮助。

谢谢

def deleteMin(self):
    self.root = self.deleteMin2(self.root)

def deleteMin2(self, node):
    if node.left is None:
        return node.right
    node.left = self.deleteMin2(node.left)
    node.count = 1 + self.size2(node.left) + self.size2(node.right)
    return node

def delete(self,key):
    self.root = self.delete2(self.root,key)

def delete2(self,node,key):
    if node is None:
        return None
    if key < node.key:
        node.left = self.delete2(node.left,key)
    elif(key > node.key):
        node.right = self.delete2(node.right,key)
    else:
        if node.right is None:
            return node.left
        if node.left is None:
            return node.right
        t = node
        node = self.min(t.right)
        node.right = self.deleteMin2(t.right)
        node.left = t.left
    node.count = self.size2(node.left) + self.size2(node.right) + 1
    return node

完整代码

import os
import pygraphviz as pgv
from collections import deque


class BST:
    root=None

    def put(self, key, val):
        self.root = self.put2(self.root, key, val)

    def put2(self, node, key, val):
        if node is None:
            #key is not in tree, create node and return node to parent
            return Node(key, val)
        if key < node.key:
            # key is in left subtree
            node.left = self.put2(node.left, key, val)
        elif key > node.key:
            # key is in right subtree
            node.right = self.put2(node.right, key, val)
        else:
            node.val = val
        node.count = 1 + self.size2(node.left) + self.size2(node.right)
        return node




    # draw the graph
    def drawTree(self, filename):
        # create an empty undirected graph
        G=pgv.AGraph('graph myGraph {}')

        # create queue for breadth first search
        q = deque([self.root])
        # breadth first search traversal of the tree
        while len(q) <> 0:
            node = q.popleft()
            G.add_node(node, label=node.key+":"+str(node.val))
            if node.left is not None:
                # draw the left node and edge
                G.add_node(node.left, label=node.left.key+":"+str(node.left.val))
                G.add_edge(node, node.left)
                q.append(node.left)
            if node.right is not None:
                # draw the right node and edge
                G.add_node(node.right, label=node.right.key+":"+str(node.right.val))
                G.add_edge(node, node.right)
                q.append(node.right)

        # render graph into PNG file
        G.draw(filename,prog='dot')
        os.startfile(filename)

    def createTree(self):
        #root
        self.put("F",6)
        self.put("D",4)
        self.put("C",3)
        self.put("B",2)
        self.put("A",1)
        self.put("E",5)
        self.put("I",9)
        self.put("G",7)
        self.put("H",8)
        self.put("J",10)

   def get(self,key):
        temp = self.root
        while temp is not None:
            #if what you are searching for is the root
            if temp.key == key:
                return temp.val
            #if it's not the root
            #check to see if what you're searching for is less than the root key
            #if so, search left
            elif temp.key > key:
                temp = temp.left
            #else search right
            else:
                temp = temp.right
        return None



    def size(self,key):
        node = self.root
        #if root is not none
        while node is not None:
        #if the given node is the current node
            if node.key == key:
                #return itself
                return self.size2(node)
        #if the node that you are at is smaller than root
            elif node.key > key:
                node = node.left
            else:
                node = node.right

    def size2(self,n):
        #if node is none
        if n is None:
            #return 0
            return 0
        else:
            #else track
            return n.count

    def depth(self, key):
        return self.depth2(self.root, key)

    def depth2(self, root, key, current_depth=0):
        #if given node is not in the tree
        if not root:
            return -1
        #inspect given key against current node (root)
        #if current node and given node is match
        elif root.key == key:
            return current_depth
        #if given node is less than current node
        elif key < root.key:
            return self.depth2(root.left, key, current_depth + 1)
        else:
            return self.depth2(root.right, key, current_depth + 1)


    def height(self,key):
        node = self.root
        #if root is not none
        while node is not None:
        #if what you are searching for is the root
            if node.key == key:
                #return itself
                return self.height2(node)
        #if the node that you are at is smaller than root
            elif node.key > key:
                node = node.left
            else:
                node = node.right


    def height2(self,n):
        if n is None:
            return -1
        else:
            #return the max
            return  1 + max(self.height2(n.left),self.height2(n.right))


    def inOrder(self,n):
        if n is None:
            return 0
        else:
            self.inOrder(n.left)
            print n.key , ": " , n.val;
            self.inOrder(n.right)

    def preOrder(self,n):
        if n is None:
            return 0
        else:
            print n.key , ": " , n.val;
            self.preOrder(n.left)
            self.preOrder(n.right)

    def postOrder(self,n):
        if n is None:
            return 0
        else:
            self.postOrder(n.left)
            self.postOrder(n.right)
            print n.key , ": " , n.val;

# ------------------------------------------------------------------------
    def deleteMin(self):
        self.root = self.deleteMin2(self.root)

    def deleteMin2(self, node):
        if node.left is None:
            return node.right
        node.left = self.deleteMin2(node.left)
        node.count = 1 + self.size2(node.left) + self.size2(node.right)
        return node

    def delete(self,key):
        self.root = self.delete2(self.root,key)

    def delete2(self,node,key):
        if node is None:
            return None
        if key < node.key:
            node.left = self.delete2(node.left,key)
        elif(key > node.key):
            node.right = self.delete2(node.right,key)
        else:
            if node.right is None:
                return node.left
            if node.left is None:
                return node.right
            t = node
            node = self.min(t.right)
            node.right = self.deleteMin2(t.right)
            node.left = t.left
        node.count = self.size2(node.left) + self.size2(node.right) + 1
        return node


class Node:
    left = None
    right = None
    key = 0
    val = 0
    count = 0



    def __init__(self, key, val):
        self.key = key
        self.val = val
        self.count += 1




bst = BST()
bst.createTree()
bst.drawTree("demo.png")
node = bst.root
print "Get: " , bst.get("C") , "\n"
print "Size: ", bst.size("D"), "\n"
print "Depth:", bst.depth("B"), "\n"
print "Height:", bst.height("B"), "\n"
print "\n In Order"
bst.inOrder(node)
print "\n Pre Order \n"
bst.preOrder(node)
print "\n Post Order \n"
bst.postOrder(node)


node = bst.root
print  bst.delete(node)

共有2个答案

毋树
2023-03-14

您可以使用del删除属性,但我不确定这是否是您想要做的:

class Node:
    def __init__(self):
        self.root = 1
n = Node()
n
<__main__.Node object at 0x101e6f278>
n.root
1
del(n.root)
n
<__main__.Node object at 0x101e6f278>
n.root
Traceback (most recent call last):
    Python Shell, prompt 6, line 1
builtins.AttributeError: 'Node' object has no attribute 'root'
伯彦君
2023-03-14

首先,你给出的代码缺少方法min。该方法在子树中查找以要删除的节点为根的最小节点:

def min(self, node):
    if node.left is None:
        return node
    else:
        return self.min(node.left)

delete 方法不返回任何内容,这就是 bst.delete(node) 打印 None 的原因。顺便说一下,delete 方法需要一个键,而不是节点本身。将上述 min 方法添加到 BST 类后,请尝试将最后两行更改为如下所示:

print "root: " + bst.root.key
bst.delete(bst.root.key)
print "root: " + bst.root.key

你会看到它先打印“F”,然后我们删除“F”,它碰巧是根。之后根变成“G”并打印出来。

要删除任意节点,只需执行bst.delete(key)其中key是要删除的节点的键。

 类似资料:
  • 我正在处理一个Path方法,它返回从给定节点到具有给定值键的节点的路径。我的代码返回正确的数字,但它们在括号内。我如何拆下支架? 实际输出为: 但它应该是:

  • 目前,我在理解如何在没有传递节点时从二进制搜索树中删除节点时遇到了一个问题。我有两个类,BSTSet和BSTNode,每个类都有一个remove方法。。 当我被传递一个节点时,我理解删除方法,但当我在根上调用remove方法并试图从node类中删除节点时,我不知道从何处开始。有人能告诉我吗?谢谢如果您想了解更多信息,请询问。

  • 我在C中实现了一个二进制搜索树。 对于delete方法,除了最后一种情况外,其他情况都可以使用,即唯一的树是父树,并且它指向两个空的子树。现在的问题是:我希望在删除子树后,打印出父树的左子树和右子树等于什么。它们和父项都应该为NULL,但是当我试图输出这些值时,我得到了一个状态访问冲突。 下面是有关删除的代码。我希望删除父节点,并设置树- 主要:

  • 我正在一个实验室工作,该实验室要求我为二进制搜索树创建一个删除方法。这是我的remove方法的代码。 运行代码时得到的输出是: 移除90后的树。70 80 85 98 100 120 移除70. 80 85 98 100 120后的树 移除85后的树。80 98 100 120 移除98后的树。80 100 120 移除80后的树。100 120 移除120后的树。100 移除100后的树。100

  • 从二叉查找树中删除节点时,您可以将节点替换为左侧的最大子节点或右侧的最小子节点。 我很难理解以下实现执行删除操作的方式。 上面的代码包括以下步骤: < li >查找替换节点。 < li >让替换节点引用已删除节点的左右子节点。 < li >让已删除节点的左右子节点将替换节点作为父节点。 < li >让替换节点引用已删除节点的父节点作为自己的父节点。 < li >清理。 我有困难的部分特别是递归。据

  • 我正在尝试从二叉查找树中删除节点。我可以成功地删除树上的任何其他节点,除了一个特殊的情况。如果目标节点有两个子节点,左边的子节点有右边的子树,我可以定位正确的替换节点,并将值切换到目标节点,但替换节点永远不会被删除。 看看上面的图片,如果我尝试删除17,程序将正确地导航到13,并用13替换17,但它不会像预期的那样删除原来的13。 我附加了我的remove方法和其中引用的方法。 这是我的Node类