简体   繁体   中英

Implementing Binary search tree in python?

I am trying to do insert function in python for BST but I am just confused on how to access the public methods properly and its giving me some grief, right now when I test it it just stops at the first test and says nonetype object has no attribute data but how am I suppose to access data when t = tree() and tree doesn't have a data constructor?

class Node(object):
    def __init__(self, data):
       self.parent = None
       self.left = None
       self.right = None
       self.data = data

class Tree(object):
# Binary Search Tree
# class constants
PREORDER = 1
INORDER = 2
POSTORDER = 3

   def __init__(self):
    # Do not create any other private variables.
    # You may create more helper methods as needed.
       self.root = None

   def print(self):
    # Print the data of all nodes in order
      self.__print(self.root)


   def __print(self, curr_node):
    # Recursively print a subtree (in order), rooted at curr_node
       if curr_node is not None:
           self.__print(curr_node.left)
           print(str(curr_node.data), end=' ')  # save space
           self.__print(curr_node.right)


   def insert(self, data):
    # Find the right spot in the tree for the new node
    # Make sure to check if anything is in the tree
    # Hint: if a node n is null, calling n.getData() will cause an error
      root = Node(data)
      print("this is my", self.root)
      if self.root is None:
          self.root = root
          return Node(data)
      else:
          if root.data == data:
              return root
          elif root.data < data:
              root.right = insert(root.right,data)
          else:
              root.left = insert(root.left, data)
      return root

And this is the test cases that I'm running with

import lab3
import unittest

class T0_tree__insert(unittest.TestCase):

    def test_balanced_binary_search_tree(self):
        print("\n")
        print("tree_insert_with_individual_check")
        t = lab3.Tree()

        t.insert(4)
        t.insert(2)
        t.insert(6)
        t.insert(1)
        t.insert(3)
        t.insert(5)
        t.insert(7)

        #The following check is without using tree as an iterator (which uses inorder traversal)
        #So this function also does not check the implementation of the traversal function

        self.assertEqual(t.root.data, 4)
        self.assertEqual(t.root.left.data, 2)
        self.assertEqual(t.root.left.left.data, 1)
        self.assertEqual(t.root.left.right.data, 3)
        self.assertEqual(t.root.right.data, 6)
        self.assertEqual(t.root.right.left.data, 5)
        self.assertEqual(t.root.right.right.data, 7)

        print("\n")

Provided two options

  1. Adds a helper function for insert to Tree (similar to helper print function __print). This allows keeping track of node we are traversing in the tree
  2. Non-recursive insert which processes through nodes.

Both options satisfy unittest.

Option 1 - Add a utility function to insert

File labe3.py

class Node(object):
    def __init__(self, data):
        self.parent = None
        self.left = None
        self.right = None
        self.data = data

class Tree(object):
    # Binary Search Tree
    # class constants
    PREORDER = 1
    INORDER = 2
    POSTORDER = 3

    def __init__(self):
        # Do not create any other private variables.
        # You may create more helper methods as needed.
        self.root = None

    def print(self):
        # Print the data of all nodes in order
        self.__print(self.root)

    def __print(self, curr_node):
        # Recursively print a subtree (in order), rooted at curr_node
        if curr_node is not None:
            self.__print(curr_node.left)
            print(str(curr_node.data), end=' ')  # save space
            self.__print(curr_node.right)

    def insert(self, d):
        print("this is my", self.root)
        if self.root is None:
          self.root = Node(d)
        else:
          self._insert(self.root, d) # here's the call to a "private" function to which we are passing nodes down, starting from root

    def _insert(self, node, value):
        ''' helper function for insert 
               node - node in BST to add value
               value - value to add
        '''
        if value < node.data:  # we know that `node` cannot be None 
                               # so it's safe to check its value! 
              if node.left:
                self._insert(node.left, value) # the recursive call is done only when `node.left` is not None
              else:
                node.left = Node(value)  # direct assignment
        else:
            if node.right:
                self._insert(node.right, value)
            else:
                node.right = Node(value)  # direct assignment
        

Option 2-non-recursive insert function

File labe3.py

class Node(object):
    def __init__(self, data):
        self.parent = None
        self.left = None
        self.right = None
        self.data = data

class Tree(object):
    # Binary Search Tree
    # class constants
    PREORDER = 1
    INORDER = 2
    POSTORDER = 3

    def __init__(self):
        # Do not create any other private variables.
        # You may create more helper methods as needed.
        self.root = None

    def print(self):
        # Print the data of all nodes in order
        self.__print(self.root)

    def __print(self, curr_node):
        # Recursively print a subtree (in order), rooted at curr_node
        if curr_node is not None:
            self.__print(curr_node.left)
            print(str(curr_node.data), end=' ')  # save space
            self.__print(curr_node.right)

    def insert(self, d):
        print("this is my", self.root)
        if self.root is None:
          self.root = Node(d)
        else:
          # current node
          current = self.root

          # Finds node to add data
          while True:
              if current.data > d:
                  if current.left == None:
                      current.left = Node(d)
                      break
                  else:
                      current = current.left

              elif current.data < d:
                  if current.right == None:
                      current.right = Node(d)
                      break
                  else:
                      current = current.right

              else:  
                break
       

File main.py

import lab3
import unittest

class T0_tree__insert(unittest.TestCase):

    def test_balanced_binary_search_tree(self):
        print("\n")
        print("tree_insert_with_individual_check")
        t = lab3.Tree()

        t.insert(4)
        t.insert(2)
        t.insert(6)
        t.insert(1)
        t.insert(3)
        t.insert(5)
        t.insert(7)

        #The following check is without using tree as an iterator (which uses inorder traversal)
        #So this function also does not check the implementation of the traversal function

        self.assertEqual(t.root.data, 4)
        self.assertEqual(t.root.left.data, 2)
        self.assertEqual(t.root.left.left.data, 1)
        self.assertEqual(t.root.left.right.data, 3)
        self.assertEqual(t.root.right.data, 6)
        self.assertEqual(t.root.right.left.data, 5)
        self.assertEqual(t.root.right.right.data, 7)

        print("\n")
        
if __name__ == '__main__':
    unittest.main()

Output

tree_insert_with_individual_check
this is my None
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>
this is my <lab3.Node object at 0x7fa4386b92e0>


.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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