How to implement a binary search tree in Python?

前端 未结 18 2018
眼角桃花
眼角桃花 2020-11-30 22:25

This is what I\'ve got so far but it is not working:

class Node:
    rChild,lChild,data = None,None,None

    def __init__(self,key):
        self.rChild = N         


        
相关标签:
18条回答
  • 2020-11-30 23:17

    Just something to help you to start on.

    A (simple idea of) binary tree search would be quite likely be implement in python according the lines:

    def search(node, key):
        if node is None: return None  # key not found
        if key< node.key: return search(node.left, key)
        elif key> node.key: return search(node.right, key)
        else: return node.value  # found key
    

    Now you just need to implement the scaffolding (tree creation and value inserts) and you are done.

    0 讨论(0)
  • 2020-11-30 23:17

    Here is a compact, object oriented, recursive implementation:

        class BTreeNode(object):
            def __init__(self, data):
                self.data = data
                self.rChild = None
                self.lChild = None
    
        def __str__(self):
            return (self.lChild.__str__() + '<-' if self.lChild != None else '') + self.data.__str__() + ('->' + self.rChild.__str__() if self.rChild != None else '')
    
        def insert(self, btreeNode):
            if self.data > btreeNode.data: #insert left
                if self.lChild == None:
                    self.lChild = btreeNode
                else:
                    self.lChild.insert(btreeNode)
            else: #insert right
                if self.rChild == None:
                    self.rChild = btreeNode
                else:
                    self.rChild.insert(btreeNode)
    
    
    def main():
        btreeRoot = BTreeNode(5)
        print 'inserted %s:' %5, btreeRoot
    
        btreeRoot.insert(BTreeNode(7))
        print 'inserted %s:' %7, btreeRoot
    
        btreeRoot.insert(BTreeNode(3))
        print 'inserted %s:' %3, btreeRoot
    
        btreeRoot.insert(BTreeNode(1))
        print 'inserted %s:' %1, btreeRoot
    
        btreeRoot.insert(BTreeNode(2))
        print 'inserted %s:' %2, btreeRoot
    
        btreeRoot.insert(BTreeNode(4))
        print 'inserted %s:' %4, btreeRoot
    
        btreeRoot.insert(BTreeNode(6))
        print 'inserted %s:' %6, btreeRoot
    

    The output of the above main() is:

    inserted 5: 5
    inserted 7: 5->7
    inserted 3: 3<-5->7
    inserted 1: 1<-3<-5->7
    inserted 2: 1->2<-3<-5->7
    inserted 4: 1->2<-3->4<-5->7
    inserted 6: 1->2<-3->4<-5->6<-7
    
    0 讨论(0)
  • 2020-11-30 23:17
    class TreeNode:
        def __init__(self, value):
            self.value = value
            self.left = None
            self.right = None
    
    
    class BinaryTree:
        def __init__(self, root=None):
            self.root = root
    
        def add_node(self, node, value):
            """
            Node points to the left of value if node > value; right otherwise,
            BST cannot have duplicate values
            """
            if node is not None:
                if value < node.value:
                    if node.left is None:
                        node.left = TreeNode(value)
                    else:
                        self.add_node(node.left, value)
                else:
                    if node.right is None:
                        node.right = TreeNode(value)
                    else:
                        self.add_node(node.right, value)
            else:
                self.root = TreeNode(value)
    
        def search(self, value):
            """
            Value will be to the left of node if node > value; right otherwise.
            """
            node = self.root
            while node is not None:
                if node.value == value:
                    return True     # node.value
                if node.value > value:
                    node = node.left
                else:
                    node = node.right
            return False
    
        def traverse_inorder(self, node):
            """
            Traverse the left subtree of a node as much as possible, then traverse
            the right subtree, followed by the parent/root node.
            """
            if node is not None:
                self.traverse_inorder(node.left)
                print(node.value)
                self.traverse_inorder(node.right)
    
    
    def main():
        binary_tree = BinaryTree()
        binary_tree.add_node(binary_tree.root, 200)
        binary_tree.add_node(binary_tree.root, 300)
        binary_tree.add_node(binary_tree.root, 100)
        binary_tree.add_node(binary_tree.root, 30)
        binary_tree.traverse_inorder(binary_tree.root)
        print(binary_tree.search(200))
    
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
  • 2020-11-30 23:18
    class Node: 
        rChild,lChild,data = None,None,None
    

    This is wrong - it makes your variables class variables - that is, every instance of Node uses the same values (changing rChild of any node changes it for all nodes!). This is clearly not what you want; try

    class Node: 
        def __init__(self, key):
            self.rChild = None
            self.lChild = None
            self.data = key
    

    now each node has its own set of variables. The same applies to your definition of Tree,

    class Tree:
        root,size = None,0    # <- lose this line!
        def __init__(self):
            self.root = None
            self.size = 0
    

    Further, each class should be a "new-style" class derived from the "object" class and should chain back to object.__init__():

    class Node(object): 
        def __init__(self, data, rChild=None, lChild=None):
            super(Node,self).__init__()
            self.data   = data
            self.rChild = rChild
            self.lChild = lChild
    
    class Tree(object):
        def __init__(self):
            super(Tree,self).__init__()
            self.root = None
            self.size = 0
    

    Also, main() is indented too far - as shown, it is a method of Tree which is uncallable because it does not accept a self argument.

    Also, you are modifying the object's data directly (t.root = Node(4)) which kind of destroys encapsulation (the whole point of having classes in the first place); you should be doing something more like

    def main():
        t = Tree()
        t.add(4)    # <- let the tree create a data Node and insert it
        t.add(5)
    
    0 讨论(0)
  • 2020-11-30 23:21

    Here is a quick example of a binary insert:

    class Node:
        def __init__(self, val):
            self.l_child = None
            self.r_child = None
            self.data = val
    
    def binary_insert(root, node):
        if root is None:
            root = node
        else:
            if root.data > node.data:
                if root.l_child is None:
                    root.l_child = node
                else:
                    binary_insert(root.l_child, node)
            else:
                if root.r_child is None:
                    root.r_child = node
                else:
                    binary_insert(root.r_child, node)
    
    def in_order_print(root):
        if not root:
            return
        in_order_print(root.l_child)
        print root.data
        in_order_print(root.r_child)
    
    def pre_order_print(root):
        if not root:
            return        
        print root.data
        pre_order_print(root.l_child)
        pre_order_print(root.r_child)    
    

    r = Node(3)
    binary_insert(r, Node(7))
    binary_insert(r, Node(1))
    binary_insert(r, Node(5))
    

         3
        / \
       1   7
          /
         5
    

    print "in order:"
    in_order_print(r)
    
    print "pre order"
    pre_order_print(r)
    
    in order:
    1
    3
    5
    7
    pre order
    3
    1
    7
    5
    
    0 讨论(0)
  • 2020-11-30 23:21

    its easy to implement a BST using two classes, 1. Node and 2. Tree Tree class will be just for user interface, and actual methods will be implemented in Node class.

    class Node():
    
        def __init__(self,val):
            self.value = val
            self.left = None
            self.right = None
    
    
        def _insert(self,data):
            if data == self.value:
                return False
            elif data < self.value:
                if self.left:
                    return self.left._insert(data)
                else:
                    self.left = Node(data)
                    return True
            else:
                if self.right:
                    return self.right._insert(data)
                else:
                    self.right = Node(data)
                    return True
    
        def _inorder(self):
            if self:
                if self.left:
                    self.left._inorder()
                print(self.value)
                if self.right:
                    self.right._inorder()
    
    
    
    class Tree():
    
        def __init__(self):
            self.root = None
    
        def insert(self,data):
            if self.root:
                return self.root._insert(data)
            else:
                self.root = Node(data)
                return True
        def inorder(self):
            if self.root is not None:
                return self.root._inorder()
            else:
                return False
    
    
    
    
    if __name__=="__main__":
        a = Tree()
        a.insert(16)
        a.insert(8)
        a.insert(24)
        a.insert(6)
        a.insert(12)
        a.insert(19)
        a.insert(29)
        a.inorder()
    

    Inorder function for checking whether BST is properly implemented.

    0 讨论(0)
提交回复
热议问题