Skip to content
This repository has been archived by the owner on Apr 29, 2020. It is now read-only.

Commit

Permalink
Merge pull request #75 from rehassachdeva/binary_tree
Browse files Browse the repository at this point in the history
Add Binary Tree implementation, tests
  • Loading branch information
goelakash committed May 15, 2016
2 parents 6ba7334 + 8794484 commit 6ba4dd0
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 0 deletions.
1 change: 1 addition & 0 deletions pydsa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
from .counting_sort import counting_sort
from .stack import Stack
from .radix_sort import radix_sort
from .binary_tree import BTNode
142 changes: 142 additions & 0 deletions pydsa/binary_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
"""
Binary Tree
A binary tree is a hierarchial data structure in which each node has at most
two children, which are referred to as the left child and the right child.
Insertion is O(1) and deletion is O(n).
Tree traversals are O(n).
Reference used: http://geeksquiz.com/binary-search-tree-set-2-delete/
and http://www.geeksforgeeks.org/write-a-c-program-to-delete-a-tree/
"""


class BTNode(object):
"""
Class to create a Binary Tree Node, insert, delete child nodes and
print inorder, preorder and postorder traversals.
>>> from pydsa import binary_tree
>>> bt = binary_tree.BTNode(1)
>>> bt.insert("left", 2)
>>> bt.insert("right", 3)
>>> bt.inorder(bt)
[2, 1, 3]
>>> bt.preorder(bt)
[1, 2, 3]
>>> bt.postorder(bt)
[2, 3, 1]
>>> bt.delete(bt.left)
>>> bt.inorder(bt)
[1, 3]
"""
def __init__(self, key, left=None, right=None):
"""
Initializes a node with value key and optionally with left and/or
right child nodes.
"""
self.left = left
self.right = right
self.key = key
self.inlist = []
self.prelist = []
self.postlist = []

def insert(self, child, key):
"""
Takes in a string child to insert the new node with value key at left
or right of current node.
"""
childNode = BTNode(key)
if child == "left":
self.left = childNode
elif child == "right":
self.right = childNode

def delete(self, root):
self.deleteUtil(self, root)

def deleteUtil(self, node, root):
"""
Recursively searches sub-trees to find root (the node to be deleted).
When found, replaces it with the child node if other is None or the
inorder successor (and recursively deletes it) if both child nodes
are not None.
"""
if node is None:
return node

node.left = self.deleteUtil(node.left, root)
node.right = self.deleteUtil(node.right, root)

if node == root:
if root.left is None:
temp = root.right
root = None
return temp

elif root.right is None:
temp = root.left
root = None
return temp

# Get inorder successor of root
temp = self.getLeftmost(root.right)
root.key = temp.key

# Recursively delete inorder successor
root.right = self.deleteUtil(root.right, temp)

return node

def getLeftmost(self, root):
"""
Returns the leftmost node in the tree rooted at root.
"""
current = root
while current.left is not None:
current = current.left
return current

def inorder(self, root):
self.inlist = []
return self.inorderUtil(root)

def inorderUtil(self, root):
"""
Recursively traverses left sub-tree, then current node and then the
right sub-tree.
"""
if root:
self.inorderUtil(root.left)
self.inlist.append(root.key)
self.inorderUtil(root.right)
return self.inlist

def preorder(self, root):
self.prelist = []
return self.preorderUtil(root)

def preorderUtil(self, root):
"""
Traverses the current node, then recursively traverses left sub-tree,
and then the right sub-tree.
"""
if root:
self.prelist.append(root.key)
self.preorderUtil(root.left)
self.preorderUtil(root.right)
return self.prelist

def postorder(self, root):
self.postlist = []
return self.postorderUtil(root)

def postorderUtil(self, root):
"""
Recursively traverses left sub-tree, then the right sub-tree and then
the current node.
"""
if root:
self.postorderUtil(root.left)
self.postorderUtil(root.right)
self.postlist.append(root.key)
return self.postlist
32 changes: 32 additions & 0 deletions pydsa/tests/test_binary_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pydsa.binary_tree import BTNode


def test_binary_tree():
bt = BTNode(1)
bt.insert("left", 2)
bt.insert("right", 3)
bt.right.insert("left", 6)
bt.right.insert("right", 7)
bt.left.insert("left", 4)
bt.left.insert("right", 5)
bt.left.left.insert("left", 8)
bt.left.left.insert("right", 9)

inlist = bt.inorder(bt)
prelist = bt.preorder(bt)
postlist = bt.postorder(bt)

assert inlist == [8, 4, 9, 2, 5, 1, 6, 3, 7]
assert prelist == [1, 2, 4, 8, 9, 5, 3, 6, 7]
assert postlist == [8, 9, 4, 5, 2, 6, 7, 3, 1]

bt.delete(bt.left)
bt.delete(bt.right)

inlist = bt.inorder(bt)
prelist = bt.preorder(bt)
postlist = bt.postorder(bt)

assert inlist == [8, 4, 9, 5, 1, 6, 7]
assert prelist == [1, 5, 4, 8, 9, 7, 6]
assert postlist == [8, 9, 4, 5, 6, 7, 1]

0 comments on commit 6ba4dd0

Please sign in to comment.