m2skills

BST python

May 23rd, 2017
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.55 KB | None | 0 0
  1. # PROGRAM TO IMPLEMENT BINARY SEARCH TREE IN PYTHON
  2. import time
  3. class node:
  4.    
  5.     # constructor method
  6.     # setting default value of left and right links to null
  7.     def __init__(self,element,left = None,right = None):
  8.         self.element = element
  9.         self.left = left
  10.         self.right = right
  11.  
  12.  
  13.     # method to update left Link   
  14.     def updateLeftLink(self,link):
  15.         self.left = link
  16.  
  17.  
  18.     # method to update right link  
  19.     def updateRightLink(self,link):
  20.         self.right = link  
  21.  
  22.  
  23.     # method to get the data element of the node
  24.     def getElement(self):
  25.         return self.element
  26.  
  27.     # method to get the Left node  
  28.     def getLeftNode(self):
  29.         return self.left
  30.    
  31.     # method to get the right node
  32.     def getRightNode(self):
  33.         return self.right  
  34.  
  35.  
  36. class BST:
  37.     def __init__(self):
  38.         self.root = None
  39.         self.pHeight = 0
  40.         self.myList = []
  41.    
  42.     # method returns true if the bst is empty
  43.     def isEmpty(self):
  44.         return self.root is None
  45.  
  46.     # method returns root of the binary search tree
  47.     def getRoot(self):
  48.         return self.root
  49.    
  50.    
  51.     # method inserts element in the binary search tree 
  52.     def insert(self,element):
  53.         tempNode = node(element)
  54.        
  55.         if self.getRoot() is None:
  56.             self.root = tempNode
  57.         else:
  58.             inserted = False
  59.             p = self.root
  60.             while not inserted:
  61.                 # if new element is greater the current element then insert it to the right
  62.                 if tempNode.getElement() > p.getElement():
  63.                     # if right link of the current is null then directly insert
  64.                     if p.getRightNode() is None:
  65.                         p.updateRightLink(tempNode)
  66.                         inserted = True
  67.                     else:
  68.                         p = p.getRightNode()
  69.                
  70.                 # if new element is less the current element then insert it to the left
  71.                 elif tempNode.getElement() < p.getElement():
  72.                     # if left link of the current is null then directly insert
  73.                     if p.getLeftNode() is None:
  74.                         p.updateLeftLink(tempNode)
  75.                         inserted = True
  76.                     else:
  77.                         p = p.getLeftNode()
  78.                
  79.    
  80.     # recursive method to display the binary tree in inorder
  81.     def displayInorder(self,tempNode):
  82.         if tempNode is None:
  83.             return
  84.         else:
  85.             self.displayInorder(tempNode.getLeftNode())
  86.             print(tempNode.getElement(), end="  ")
  87.             self.displayInorder(tempNode.getRightNode())
  88.  
  89.    
  90.     # recursive method to display the binary tree in preorder
  91.     def displayPreorder(self,tempNode):
  92.         if tempNode is None:
  93.             return
  94.         else:
  95.             print(tempNode.getElement(), end="  ")
  96.             self.displayPreorder(tempNode.getLeftNode())
  97.             self.displayPreorder(tempNode.getRightNode())
  98.  
  99.  
  100.     # recursive method to display binary tree in postorder     
  101.     def displayPostorder(self,tempNode):
  102.         if tempNode is None:
  103.             return
  104.         else:
  105.             self.displayPostorder(tempNode.getLeftNode())
  106.             self.displayPostorder(tempNode.getRightNode())
  107.             print(tempNode.getElement(), end="  ")
  108.  
  109.  
  110.     # method to display all Leaf nodes of the binary tree
  111.     # traversing in inorder method and if both left and right links are null then we print the Leaf node
  112.     def displayLeafNodes(self,tempNode):
  113.         if tempNode is None:
  114.             return
  115.        
  116.         self.displayLeafNodes(tempNode.getLeftNode())
  117.  
  118.         # check if it is a leaf node
  119.         if tempNode.getLeftNode() is None and tempNode.getRightNode() is None:
  120.             print(tempNode.getElement(), end="  ")
  121.  
  122.         self.displayLeafNodes(tempNode.getRightNode())
  123.        
  124.        
  125.     # method to display the max element of the Binary Tree
  126.     # max element is the rightmost node of the bst
  127.     def maxElement(self):
  128.        
  129.         # check if the bst is empty or not
  130.         if self.isEmpty():
  131.             return -999999      # assuming that -999999 never appears in the BST
  132.            
  133.         tempNode = self.getRoot()
  134.         # traverse to the rightmost node in the bst
  135.         while tempNode.getRightNode() is not None:
  136.             tempNode = tempNode.getRightNode()
  137.        
  138.         return tempNode.getElement()
  139.    
  140.    
  141.     # method to display the min element of the Binary Tree
  142.     # min element is the leftmost node of the bst
  143.     def minElement(self):
  144.        
  145.         # check if the bst is empty or not
  146.         if self.isEmpty():
  147.             return 999999       # assuming that 999999 never appears in the BST
  148.            
  149.         tempNode = self.getRoot()
  150.         # traverse to the rightmost node in the bst
  151.         while tempNode.getLeftNode() is not None:
  152.             tempNode = tempNode.getLeftNode()
  153.        
  154.         return tempNode.getElement()
  155.    
  156.    
  157.     # method to find the common ancestor of 2 nodes
  158.     # method assumes that both the nodes are already present in the binary tree
  159.     def commonAncestor(self, e1, e2):
  160.        
  161.         tempNode = self.getRoot()
  162.         parent = self.getRoot()
  163.        
  164.         found = False
  165.         while not found:
  166.             data = tempNode.getElement()
  167.             # if both the elements are greater than the data then traverse right
  168.             if data < e1 and data < e2:
  169.                 parent = tempNode
  170.                 tempNode = tempNode.getRightNode()
  171.  
  172.             # if the element are less than data traverse left  
  173.             elif data > e1 and data > e2:
  174.                 parent = tempNode
  175.                 tempNode = tempNode.getLeftNode()
  176.                
  177.             # if one of the element is equal to the data then the parent node is the required Ancestor 
  178.             elif data == e1 or data == e2:
  179.                 print("\nThe common Ancestor of " + str(e1) + " and " + str(e2) + " is " + str(parent.getElement()))
  180.                 found = True
  181.            
  182.             # if one element is greater and other is smaller then current node is the required ancestor
  183.             else:
  184.                 print("\nThe common Ancestor of " + str(e1) + " and " + str(e2) + " is " + str(tempNode.getElement()))
  185.                 found = True
  186.            
  187.    
  188.     # method to search an element in the binary search tree
  189.     # if found method returns true
  190.     def search(self, element):
  191.    
  192.         # if the bst is empty return false
  193.         if self.isEmpty():
  194.             return False
  195.            
  196.         tempNode = self.getRoot()
  197.         found = False
  198.        
  199.         while not found:
  200.            
  201.             # if tempNode is null then the element is not present
  202.             # break out of the loop
  203.             if tempNode is None:
  204.                 break
  205.            
  206.             # if the element are less than current data traverse right
  207.             if tempNode.getElement() > element:
  208.                 tempNode = tempNode.getLeftNode()
  209.                
  210.             # if the element are greater than current data traverse left
  211.             elif tempNode.getElement() < element:
  212.                 tempNode = tempNode.getRightNode()
  213.                
  214.             # if the element is equal to the current data then set found to true   
  215.             elif tempNode.getElement() == element:
  216.                 found = True
  217.                
  218.         return found
  219.  
  220.  
  221.     # method to display all nodes at a distance k from the root of the binary tree
  222.     # traversing in preorder method and if distance of node is k then we print the node
  223.     def displayNodesAtDistance(self,tempNode, distance, count):
  224.  
  225.         if tempNode is None:
  226.             return
  227.         if count > distance:
  228.             return
  229.            
  230.         if count == distance:
  231.             print(tempNode.getElement())
  232.  
  233.         self.displayNodesAtDistance(tempNode.getLeftNode(), distance, count + 1)
  234.         self.displayNodesAtDistance(tempNode.getRightNode(), distance, count + 1)
  235.        
  236.        
  237.     # this function resets the tree height and then calls the height function
  238.     def height(self):
  239.         self.pHeight = 0
  240.         return self.height_helper(self.root, 0)
  241.        
  242.    
  243.     # method to find the height of the binary search tree
  244.     def height_helper(self,tempNode,tempHeight):
  245.         if tempNode is None:
  246.             return 0
  247.         else:
  248.            
  249.             tempHeight = self.height_helper(tempNode.getLeftNode(), tempHeight)
  250.             tempHeight += 1
  251.            
  252.             if tempNode == self.root:
  253.                 if self.pHeight < tempHeight:
  254.                     self.pHeight = tempHeight
  255.                     tempHeight = 0
  256.            
  257.             tempHeight = self.height_helper(tempNode.getRightNode(), tempHeight)
  258.  
  259.             if tempNode == self.root:
  260.                 if self.pHeight < tempHeight:
  261.                     self.pHeight = tempHeight
  262.                     tempHeight = 0
  263.  
  264.         return self.pHeight + 1
  265.            
  266.    
  267.     # method to delete an element from the binary search tree
  268.     def deleteElement(self, element):
  269.         removed = False
  270.  
  271.         tempNode = self.getRoot()
  272.         parent = self.getRoot()
  273.        
  274.         while not removed:
  275.             if tempNode.getElement() > element:
  276.                 parent = tempNode
  277.                 tempNode = tempNode.getLeftNode()
  278.                
  279.             elif tempNode.getElement() < element:
  280.                 parent = tempNode
  281.                 tempNode = tempNode.getRightNode()
  282.                
  283.             elif tempNode.getElement() == element:
  284.                
  285.                 parentData = parent.getElement()
  286.                 nodeData = tempNode.getElement()
  287.                
  288.                 # checking if the node is a leaf node
  289.                 if tempNode.getLeftNode() is None and tempNode.getRightNode() is None:
  290.                    
  291.                     if parentData > nodeData:
  292.                         parent.updateLeftLink(None)
  293.  
  294.                     elif parentData < nodeData:
  295.                         parent.updateRightLink(None)
  296.  
  297.                     removed = True
  298.                     del tempNode
  299.                        
  300.                 # checking if the node has only a left subtree
  301.                 elif tempNode.getLeftNode() is not None and tempNode.getRightNode() is None:
  302.                    
  303.                     if parentData > nodeData:
  304.                         parent.updateLeftLink(tempNode.getLeftNode())
  305.                    
  306.                     elif parentData > nodeData:
  307.                         parent.updateRightLink(tempNode.getLeftNode())
  308.  
  309.                     del tempNode
  310.                     removed = True
  311.                        
  312.                 # checking is the node has only a right subtree
  313.                 elif tempNode.getLeftNode() is None and tempNode.getRightNode() is not None:
  314.                    
  315.                     if parentData > nodeData:
  316.                         parent.updateLeftLink(tempNode.getRightNode())
  317.                    
  318.                     elif parent.getElement() > tempNode.getElement():
  319.                         parent.updateRightLink(tempNode.getRightNode())
  320.                    
  321.                     del tempNode
  322.                     removed = True
  323.                
  324.                 # checking if the node to ne deleted is the root node
  325.                 elif self.getRoot().getElement() == tempNode.getElement():
  326.                    
  327.                     if tempNode.getLeftNode() is None:
  328.                         self.root = tempNode.getRightNode()
  329.                        
  330.                     elif tempNode.getRightNode() is None:
  331.                         self.root = tempNode.getLeftNode()
  332.                        
  333.                     else:
  334.                         q = tempNode.getRightNode()
  335.                         self.root = q
  336.                         r = tempNode.getLeftNode()
  337.                         while q.getLeftNode() is not None:
  338.                             q = q.getLeftNode()
  339.                        
  340.                         q.updateLeftLink(r)
  341.  
  342.                     del tempNode
  343.                     removed = True
  344.                        
  345.                        
  346.                 elif tempNode.getLeftNode() is None and tempNode.getRightNode() is None:
  347.                    
  348.                     if parentData > nodeData:
  349.                         parent.updateLeftLink(tempNode.getRightNode())
  350.  
  351.                     elif parentData < nodeData:
  352.                         parent.updateRightLink(tempNode.getRightNode())
  353.  
  354.                     q = tempNode.getLeftNode()
  355.                     r = tempNode.getRightNode()
  356.                     while r.getLeftNode() is not None:
  357.                         r = r.getLeftNode()
  358.  
  359.                     r.updateLeftLink(q)
  360.  
  361.                     del tempNode
  362.                     removed = True
  363.  
  364.     def deleteMin(self):
  365.         element = self.minElement()
  366.         self.deleteElement(element)
  367.  
  368.     def deleteMax(self):
  369.         element = self.maxElement()
  370.         self.deleteElement(element)
  371.    
  372. # main function
  373.  
  374. b1 = BST()
  375. b1.insert(7)
  376. b1.insert(29)
  377. b1.insert(25)
  378. b1.insert(36)
  379. b1.insert(71)
  380. b1.insert(24)
  381. b1.insert(5)
  382. b1.insert(9)
  383. b1.insert(1)
  384. root = b1.getRoot()
  385. print("\nThe inorder traversal of the BST is : ", end=" ")
  386. b1.displayInorder(root)
  387.  
  388. print("\n\nThe Preorder traversal of the BST is : ", end=" ")
  389. b1.displayPreorder(root)
  390.  
  391. print("\n\nThe Postorder traversal of the BST is : ", end=" ")
  392. b1.displayPostorder(root)
  393.  
  394. print("\n\nThe Leaf Nodes of the BST are : ", end=" ")
  395. b1.displayLeafNodes(root)
  396.  
  397. print("\n\nThe Largest Element of the BST is : " + str(b1.maxElement()))
  398.  
  399. print("\nThe Smallest Element of the BST is : " + str(b1.minElement()))
  400.  
  401. # b1.deleteMax()
  402. # b1.deleteMin()
  403.  
  404. print("\n\nThe Inorder traversal of the BST is : ", end=" ")
  405. b1.displayInorder(root)
  406.  
  407. b1.commonAncestor(6,1)
  408. b1.commonAncestor(1,9)
  409. b1.commonAncestor(9,36)
  410.  
  411. print("\n\nNodes at a distance 2 from the root node are : ")
  412. b1.displayNodesAtDistance(root,2,0)
  413.  
  414. print("\n")
  415. # searching for the elements in the binary search tree
  416. print(b1.search(25))
  417. print(b1.search(37))
  418.  
  419. print("\n\nThe height of the binary search tree is : " + str(b1.height()))
  420.  
  421. b1.deleteElement(36)
  422. b1.deleteMin()
  423. b1.deleteMax()
  424.  
  425. print("\nThe Breadth First Traversal of the BST is :", end = " ")
  426. b1.bfs()
  427.  
  428.  
  429. print("\nThe inorder traversal of the BST is : ", end=" ")
  430.  
  431. b1.displayInorder(root)
  432. print()
  433. b1.kthSmallest(root,3)
Add Comment
Please, Sign In to add comment