#!/usr/bin/python
""" A model containing Node class """
__author__ = "Lin Chen"
__version__ = "0.1"
class Node:
"""Single node in the binary search tree"""
def __init__(self, data):
"""Initialize a Node
Args:
data : data saved in the node
"""
self._data = data
self._left = None
self._right = None
self._parent = None
@property
def data(self):
return self._data
@data.setter
def data(self, d):
self._data = d
@data.deleter
def data(self):
del self._data
@property
def left(self):
return self._left
@left.setter
def left(self, n):
self._left = n
@left.deleter
def left(self):
del self._left
@property
def right(self):
return self._right
@right.setter
def right(self, n):
self._right = n
@right.deleter
def right(self):
del self._right
@property
def parent(self):
return self._parent
@parent.setter
def parent(self, n):
self._parent = n
@parent.deleter
def parent(self):
del self._parent
def __str__(self):
return str(self._data)
#!/usr/bin/python
""" A model containing Binary Search Tree"""
from NodeModule import Node
class BST(object):
"""Class of binary search tree"""
def __init__(self):
"""Initialize a binary search tree
"""
self._root = None
@property
def root(self):
return self._root
@root.setter
def root(self, n):
self._root = n
@root.deleter
def root(self):
del self._root
def isEmpty(self):
return (self._root is None)
def size(self):
return self.getSize(self._root)
def getSize(self, n):
if n is None:
return 0
return 1 + self.getSize(n.left) + self.getSize(n.right)
def height(self):
return self.getHeight(self._root)
def getHeight(self, n):
if n is None:
return 0
if n.left is None and n.right is None:
return 1
l = self.getHeight(n.left)
r = self.getHeight(n.right)
h = 1+l if l > r else 1+r
return h
def inorderWalk(self):
"""Print elements in ascending order, O(n)"""
if self._root is not None:
self.printLDR(self._root)
print()
def printLDR(self, n):
if n is None:
return
self.printLDR(n.left)
print('<'+str(n)+'>', end = ' '),
self.printLDR(n.right)
def preWalk(self):
"""Print element in pre-order, O(n)"""
if self._root is not None:
self.printDLR(self._root)
print()
def printDLR(self, n):
if n is None:
return
print('<'+str(n)+'>', end = ' '),
self.printDLR(n.left)
self.printDLR(n.right)
def postWalk(self):
"""Print element in pre-order, O(n)"""
if self._root is not None:
self.printLRD(self._root)
print()
def printLRD(self, n):
if n is None:
return
self.printLRD(n.left)
self.printLRD(n.right)
print('<'+str(n)+'>', end = ' '),
def search(self, v):
"""Search if a value has been saved in the binary search tree
Returns:
Node, return the node containing the value if find it in tree, None otherwise"""
if self._root is not None:
return self.searchTree(self._root, v)
def searchTree(self, n, v):
if n is None or v == n.data:
return n
if v < n.data:
return self.searchTree(n.left, v)
else:
return self.searchTree(n.right, v)
def min(self):
"""Return node containing minimum value in the binary search tree"""
n = self.getMin(self._root)
return n
def getMin(self, n):
if n is None or n.left is None:
return n
return self.getMin(n.left)
def max(self):
"""Return node containing maximum value in the binary search tree"""
n = self.getMax(self._root)
return n
def getMax(self, n):
if n is None or n.right is None:
return n
return self.getMax(n.right)
def successor(self, v):
"""Return the node with the smallest key greater than v"""
n = self.search(v)
if n is None:
return None
return self.getSuccessor(n)
def getSuccessor(self, n):
if n.right is not None:
return self.getMin(n.right)
y = n.parent
while (y is not None) and (n is y.right):
n = y
y = y.parent
return y
def predecessor(self, v):
"""Return the node with the largest key less than v"""
n = self.search(v)
if n is None:
return None
return self.getPredecessor(n)
def getPredecessor(self, n):
if n.left is not None:
return self.getMax(n.left)
y = n.parent
while (y is not None) and (n is y.left):
n = y
y = y.parent
return y
def insert(self, v):
if self.search(v) is not None:
return
p = None
current = self._root
while current is not None:
p = current
current = p.left if v < p.data else p.right
n = Node(v)
n.parent = p
if p is None:
self._root = n
else:
if v < p.data:
p.left = n
else:
p.right = n
def transplant(self, u, v):
"""Replaces the subtree rooted at node u with the subtree rooted at node v"""
if u.parent is None:
self._root = v
elif u == u.parent.left:
u.parent.left = v
else:
u.parent.right = v
if v is not None:
v.parent = u.parent
def delete(self, e):
"""Delete the node which contains data e"""
z = self.search(e)
if z is None:
return;
if z.left is None:
self.transplant(z, z.right)
elif z.right is None:
self.transplant(z, z.left)
else:
y = self.getMin(z.right)
if y.parent != z:
self.transplant(y, y.right)
y.right = z.right
y.right.parent = y
self.transplant(z, y)
y.left = z.left
y.left.parent = y
#!/usr/bin/python
from BSTModule import BST
def main():
t = BST();
# Create tree
t.insert(8);
t.insert(3);
t.insert(10);
t.insert(1);
t.insert(6);
t.insert(14);
t.insert(4);
t.insert(7);
t.insert(13);
t.insert(15);
# Display tree
t.inorderWalk()
t.preWalk()
t.postWalk()
# size
print('Size: ', t.size())
# height
print('Height: ', t.height())
# search
print(t.search(7)) # 7
print(t.search(20)) # None
# min
print(t.min()) # 1
# max
print(t.max()) # 15
# successor
print(t.successor(3)) # 4
print(t.successor(7)) # 8
print(t.successor(8)) # 10
print(t.successor(15)) # None
# predecessor
print(t.predecessor(13)) # 10
print(t.predecessor(10)) # 8
print(t.predecessor(8)) # 7
print(t.predecessor(1)) # None
# delete
t.delete(3);
t.inorderWalk();
if __name__ == '__main__':
main()