二进制搜索树,删除节点,这里需要帮助(重新发布)

时间:2016-06-30 17:49:12

标签: python methods binary-search-tree

我的代码看起来像这样:

class Treenode:
    def __init__(self,data,left=None,right=None):
        self.data=data
        self.left=left
        self.right=right

    def __str__(self):
        return str(self.data)

    def delete(self):
        child=self.left
        grandchild=child.right
        print(grandchild)
        if self.left == self.right==None:
            return None
        if self.left==None:
            return self.right
        if self.right==None:
            return self.left
        if grandchild:
            while grandchild.right:
                child = grandchild
                grandchild = child.right
            self.data = grandchild.data
            child.right = grandchild.left
        else:
            self.left = child.left
            self.data = child.data
        return self

class Bintree:
    def __init__(self):
        self.root = None

    def put(self,data):
        if self.root == None:
            self.root = Treenode(data)
            return
        p = self.root
        while True:
            if data < p.data:
                if p.left == None:
                    p.left = Treenode(data)
                    return
                else:
                    p = p.left
            elif data > p.data:
                if p.right == None:
                    p.right = Treenode(data)
                    return
                else:
                    p = p.right
            elif data == p.data:
                return False
            else:
                return

    def exists(self, data):
        return finns(self.root, data)

    def isempty(self):
        return self.root == None

    def height(self):
        def hp(tree):
            if tree is None:
                return 0
            else:
                return 1 + max(hp(tree.left), hp(tree.right))
        return hp(self.root)

    def printTree(self):
        skriv(self.root)

    def remove(self, data):
        if self.root and self.root.data == data:  #self.root kanske inte behövs, undersök
            self.root = self.root.delete()
            return
        else:
            parent = self.root
            while parent:
                if data < parent.data:
                    child = parent.left
                    if child and child.data== data:
                        parent.left = child.delete()
                        return
                    parent = child
                else:
                    child = parent.right
                    if child and child.data == data:
                        parent.right = child.delete()
                        return
                    parent = child



def skriv(tree):
    if tree == None:
        return
    skriv(tree.left)
    print(tree.data)
    skriv(tree.right)

def finns(roten, key):
    if roten == None:
        return False
    if key == roten.data:
        return True
    elif key < roten.data:
        return finns(roten.left, key)
    else:
        return finns(roten.right, key)

关于我的代码的所有内容都有效,我只是简单地添加了(删除方法)删除方法和删除方法。我拼命想要了解删除方法,但我无法理解。我使用此代码来运行该事物并查看树的实现方式:

from labb8test import Bintree
from labb8test import Treenode

tree = Bintree()    
tree.put(8)    
tree.put(3)
tree.put(1)
tree.put(6)
tree.put(4)
tree.put(7)
tree.put(10)
tree.put(14)
tree.put(13)
tree.remove(6)
tree.printTree()

我试图在纸上画它,特别是看看while循环是如何工作的。根据我上面的代码,我认为它是这样的:

child = self.left(child = 3)grandchild = child.right = self,left.right = 6。如果孙子(是,6)而孙子。(是,7)孩子=孙子,3 - > 6孙子= child.right(这是否需要,6 ---&gt; 6?)self.data = grandchild.data(8 ---&gt; 6)child.right = grandchild.left(6 ----&gt; 4)??

但它不可能是这样,因为那时while循环永远不会结束。有没有人可以帮我理解我失去的地方?

1 个答案:

答案 0 :(得分:2)

我建议您使用普林斯顿算法中的这些材料: http://algs4.cs.princeton.edu/32bst/

delete方法正在使用此方法从bst中删除节点。

  

删除。我们可以以类似的方式继续删除任何具有的节点   一个孩子(或没有孩子),但我们可以做些什么来删除一个节点   有两个孩子?我们留下了两个链接,但在中有一个位置   父节点只有其中一个。首先是对这种困境的回答   T. Hibbard在1962年提出的是通过替换它来删除节点x   与其继任者。因为x有一个正确的孩子,它的继承者是   右子树中具有最小键的节点。更换   保留树中的顺序,因为x.key之间没有键   和继任者的关键。我们完成了用它替换x的任务   继任者

     

四个(!)简单步骤:

     
      
  • 在t
  • 中保存指向要删除的节点的链接   
  • 将x设置为指向其后继min(t.right)
  •   
  • 将x的右侧链接(应该指向包含大于x.key的所有键的BST)设置为deleteMin(t.right),   链接到包含所有大于x.key的键的BST   删除后。
  •   
  • 将x的左侧链接(为空)设置为t.left(所有小于已删除密钥及其后继密钥的密钥)。
  •   

enter image description here