简体   繁体   English

遍历二进制搜索树时出错-Python

[英]Error while traversing binary search tree - Python

I'm trying to run the classic algorithms for tree traversing. 我正在尝试运行用于树遍历的经典算法。 I've created an example tree and tested whether the preorder , inorder and postorder algorithms worked correctly. 我创建了一个示例树,并测试了preorderinorderpostorder算法是否正常工作。 But after that tests I get incorrect results. 但是在那次测试之后,我得到了不正确的结果。 When I run the preorder algorithm starting on node A , I get this sequence {A,C,H,D,G}, when I should be getting {A,C,D,H,G}. 当我从节点A开始运行排序算法时,我应该得到{A,C,D,H,G}时得到此序列{A,C,H,D,G}。

I don't think I'm missing something in the traversing part of the code, but maybe I am in the tree definition. 我不认为我在代码的遍历部分中缺少任何内容,但也许我在树定义中。 I can't see the error myself. 我自己看不到错误。 Thanks in advanced. 提前致谢。

class Node:
    id = 0
    def __init__(self,value):
        self.id = id
        Node.id += 1
        self.value = value
        self.left_child = None
        self.right_child = None

    def insert_left_child(self, new_node):
        if self.is_leaf():
            self.insert_left_child(new_node);
        else:
            # As there is already a left child, the pointers must be
            # redistributed to include the new child. 
            current_left_child = self.left_subtree()
            self.insert_left_child(new_node)
            new_node.insert_left_child(current_left_child)

    def insert_right_child(self, new_node):
        if self.is_leaf():
            self.insert_right_child(new_node);
        else:
            # As there is already a right child, the pointers must be
            # redistributed to include the new child.
            current_right_child = self.right_subtree()
            self.insert_right_child(new_node)
            new_node.insert_right_child(current_right_child)

    def left_subtree(self):
        return self.left_child

    def right_subtree(self):
        return self.right_child

    def insert_left_child(self,child_node):
        self.left_child = child_node

    def has_left_children(self):
        return self.left_child != None

    def insert_right_child(self,child_node):
        self.right_child = child_node

    def has_right_children(self):
        return self.right_child != None

    def is_leaf(self):
        return (not self.has_left_children()) & (not self.has_right_children())


class BinaryTree:
    def __init__(self):
        self.root = Node('root')

    def preorder(self,current_node = None):
        if current_node is None:
            current_node = self.root

        print current_node.value
        if current_node.has_left_children():
            self.inorder(current_node.left_subtree())
        if current_node.has_right_children():
            self.inorder(current_node.right_subtree())

    def inorder(self,current_node = None):
        if current_node is None:
            current_node = self.root

        if current_node.has_left_children():
            self.inorder(current_node.left_subtree())
        print current_node.value
        if current_node.has_right_children():
            self.inorder(current_node.right_subtree())

    def postorder(self,current_node = None):
        if current_node is None:
            current_node = self.root

        if current_node.has_left_children():
            self.inorder(current_node.left_subtree())
        if current_node.has_right_children():
            self.inorder(current_node.right_subtree())
        print current_node.value

# Main routine

#           root
#       A           B
#     C   D       E   F
#        H G

tree = BinaryTree()

A = Node('A')
B = Node('B')
C = Node('C')
D = Node('D')
E = Node('E')
F = Node('F')
G = Node('G')
H = Node('H')

tree.root.insert_left_child(A)
tree.root.insert_right_child(B)
A.insert_left_child(C)
A.insert_right_child(D)
B.insert_left_child(E)
B.insert_right_child(F)
D.insert_left_child(H)
D.insert_right_child(G)

tree.preorder(A)

You call inorder methods from preorder method. 您可以从preorder inorder方法中调用inorder方法。 So you change the algorithm when getting deeper in the tree: 因此,当您深入树中时,可以更改算法:

    if current_node.has_left_children():
        self.inorder(current_node.left_subtree())
    if current_node.has_right_children():
        self.inorder(current_node.right_subtree())

should be: 应该:

    if current_node.has_left_children():
        self.preorder(current_node.left_subtree())
    if current_node.has_right_children():
        self.preorder(current_node.right_subtree())

There is a lot to be said about this code. 关于此代码,有很多要说的。 You should get rid of all the superfluous accessor-methods, and access left and right children immediately. 您应该摆脱所有多余的访问器方法,并立即访问左右孩子。 Also, consider making eg is_leaf a property instead of a method. 另外,考虑将is_leaf设为属性而不是方法。 But the thing that probably causes your error is the following: 但是,可能导致您的错误的是以下内容:

class Node:
    id = 0
    def __init__(self,value):
        self.id = id
        Node.id += 1

This does not do what you think it does. 这并没有按照您的想法做。 It assigns the builtin function "id" to your id, thus making all nodes the same id. 它将内置函数“ id”分配给您的id,从而使所有节点都具有相同的id。

To fix this, either use Node.id, or even better, use this: 要解决此问题,请使用Node.id,或者甚至更好,请使用以下命令:

from itertools import count


class Node(object): # if on python3, you don't need to inherit from object

    IDGEN = count()

    def __init__(self, value):
        self.id = self.IDGEN.next()
        ...

复制粘贴错误在这里,您错误地调用了preorder (和postorder )中的inorder

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

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