How to implement a binary search tree in Python?

前端 未结 18 2017
眼角桃花
眼角桃花 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 22:54

    The Op's Tree.insert method qualifies for the "Gross Misnomer of the Week" award -- it doesn't insert anything. It creates a node which is not attached to any other node (not that there are any nodes to attach it to) and then the created node is trashed when the method returns.

    For the edification of @Hugh Bothwell:

    >>> class Foo(object):
    ...    bar = None
    ...
    >>> a = Foo()
    >>> b = Foo()
    >>> a.bar
    >>> a.bar = 42
    >>> b.bar
    >>> b.bar = 666
    >>> a.bar
    42
    >>> b.bar
    666
    >>>
    
    0 讨论(0)
  • 2020-11-30 22:55

    The accepted answer neglects to set a parent attribute for each node inserted, without which one cannot implement a successor method which finds the successor in an in-order tree walk in O(h) time, where h is the height of the tree (as opposed to the O(n) time needed for the walk).

    Here is an implementation based on the pseudocode given in Cormen et al., Introduction to Algorithms, including assignment of a parent attribute and a successor method:

    class Node(object):
        def __init__(self, key):
            self.key = key
            self.left = None
            self.right = None
            self.parent = None
    
    
    class Tree(object):
        def __init__(self, root=None):
            self.root = root
    
        def insert(self, z):
            y = None
            x = self.root
            while x is not None:
                y = x
                if z.key < x.key:
                    x = x.left
                else:
                    x = x.right
            z.parent = y
            if y is None:
                self.root = z       # Tree was empty
            elif z.key < y.key:
                y.left = z
            else:
                y.right = z
    
        @staticmethod
        def minimum(x):
            while x.left is not None:
                x = x.left
            return x
    
        @staticmethod
        def successor(x):
            if x.right is not None:
                return Tree.minimum(x.right)
            y = x.parent
            while y is not None and x == y.right:
                x = y
                y = y.parent
            return y
    

    Here are some tests to show that the tree behaves as expected for the example given by DTing:

    import pytest
    
    @pytest.fixture
    def tree():
        t = Tree()
        t.insert(Node(3))
        t.insert(Node(1))
        t.insert(Node(7))
        t.insert(Node(5))
        return t
    
    def test_tree_insert(tree):
        assert tree.root.key == 3
        assert tree.root.left.key == 1
        assert tree.root.right.key == 7
        assert tree.root.right.left.key == 5
    
    def test_tree_successor(tree):
        assert Tree.successor(tree.root.left).key == 3
        assert Tree.successor(tree.root.right.left).key == 7
    
    if __name__ == "__main__":
        pytest.main([__file__])
    
    0 讨论(0)
  • 2020-11-30 22:59

    I find the solutions a bit clumsy on the insert part. You could return the root reference and simplify it a bit:

    def binary_insert(root, node):
        if root is None:
            return node
        if root.data > node.data:
            root.l_child = binary_insert(root.l_child, node)
        else:
            root.r_child = binary_insert(root.r_child, node)
        return root
    
    0 讨论(0)
  • 2020-11-30 23:04
        def BinaryST(list1,key):
        start = 0
        end = len(list1)
        print("Length of List: ",end)
    
        for i in range(end):
            for j in range(0, end-i-1):
                if(list1[j] > list1[j+1]):
                    temp = list1[j]
                    list1[j] = list1[j+1]
                    list1[j+1] = temp
    
        print("Order List: ",list1)
    
        mid = int((start+end)/2)
        print("Mid Index: ",mid)
    
        if(key == list1[mid]):
            print(key," is on ",mid," Index")
    
        elif(key > list1[mid]):
            for rindex in range(mid+1,end):
                if(key == list1[rindex]):
                    print(key," is on ",rindex," Index")
                    break
                elif(rindex == end-1):
                    print("Given key: ",key," is not in List")
                    break
                else:
                    continue
    
        elif(key < list1[mid]):
            for lindex in range(0,mid):
                if(key == list1[lindex]):
                    print(key," is on ",lindex," Index")
                    break
                elif(lindex == mid-1):
                    print("Given key: ",key," is not in List")
                    break
                else:
                    continue
    
    
    size = int(input("Enter Size of List: "))
    list1 = []
    for e in range(size):
        ele = int(input("Enter Element in List: "))
        list1.append(ele)
    
    key = int(input("\nEnter Key for Search: "))
    
    print("\nUnorder List: ",list1)
    BinaryST(list1,key)
    
    0 讨论(0)
  • 2020-11-30 23:05

    The problem, or at least one problem with your code is here:-

    def insert(self,node,someNumber):
        if node is None:
            node = Node(someNumber)
        else:
            if node.data > someNumber:
                self.insert(node.rchild,someNumber)
            else:
                self.insert(node.rchild, someNumber)
        return
    

    You see the statement "if node.data > someNumber:" and the associated "else:" statement both have the same code after them. i.e you do the same thing whether the if statement is true or false.

    I'd suggest you probably intended to do different things here, perhaps one of these should say self.insert(node.lchild, someNumber) ?

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

    Another Python BST solution

    class Node(object):
        def __init__(self, value):
            self.left_node = None
            self.right_node = None
            self.value = value
    
        def __str__(self):
            return "[%s, %s, %s]" % (self.left_node, self.value, self.right_node)
    
        def insertValue(self, new_value):
            """
            1. if current Node doesnt have value then assign to self
            2. new_value lower than current Node's value then go left
            2. new_value greater than current Node's value then go right
            :return:
            """
            if self.value:
                if new_value < self.value:
                    # add to left
                    if self.left_node is None:  # reached start add value to start
                        self.left_node = Node(new_value)
                    else:
                        self.left_node.insertValue(new_value)  # search
                elif new_value > self.value:
                    # add to right
                    if self.right_node is None:  # reached end add value to end
                        self.right_node = Node(new_value)
                    else:
                        self.right_node.insertValue(new_value)  # search
            else:
                self.value = new_value
    
        def findValue(self, value_to_find):
            """
            1. value_to_find is equal to current Node's value then found
            2. if value_to_find is lower than Node's value then go to left
            3. if value_to_find is greater than Node's value then go to right
            """
            if value_to_find == self.value:
                return "Found"
            elif value_to_find < self.value and self.left_node:
                return self.left_node.findValue(value_to_find)
            elif value_to_find > self.value and self.right_node:
                return self.right_node.findValue(value_to_find)
            return "Not Found"
    
        def printTree(self):
            """
            Nodes will be in sequence
            1. Print LHS items
            2. Print value of node
            3. Print RHS items
            """
            if self.left_node:
                self.left_node.printTree()
            print(self.value),
            if self.right_node:
                self.right_node.printTree()
    
        def isEmpty(self):
            return self.left_node == self.right_node == self.value == None
    
    
    def main():
        root_node = Node(12)
        root_node.insertValue(6)
        root_node.insertValue(3)
        root_node.insertValue(7)
    
        # should return 3 6 7 12
        root_node.printTree()
    
        # should return found
        root_node.findValue(7)
        # should return found
        root_node.findValue(3)
        # should return Not found
        root_node.findValue(24)
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
提交回复
热议问题