2019-04-09 11:38:46 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# vim: set ts=2 sw=2 et tw=80:
|
|
|
|
|
2019-04-23 11:37:26 +00:00
|
|
|
import sys
|
|
|
|
|
2019-04-09 11:38:46 +00:00
|
|
|
class Node:
|
|
|
|
def __init__(self, k):
|
|
|
|
self.key = k
|
|
|
|
self.left = None
|
|
|
|
self.right = None
|
2019-04-23 11:37:26 +00:00
|
|
|
self.parent = None
|
|
|
|
|
|
|
|
def set_left(self, kNode):
|
|
|
|
kNode.parent = self
|
|
|
|
self.left = kNode
|
|
|
|
|
|
|
|
def set_right(self, kNode):
|
|
|
|
kNode.parent = self
|
|
|
|
self.right = kNode
|
|
|
|
|
|
|
|
|
|
|
|
tree = Node(77)
|
|
|
|
tree.set_left(Node(30))
|
|
|
|
tree.left.set_left(Node(21))
|
|
|
|
tree.left.set_right(Node(33))
|
|
|
|
tree.left.right.set_left(Node(31))
|
|
|
|
tree.left.right.set_right(Node(50))
|
|
|
|
tree.set_right(Node(78))
|
|
|
|
tree.right.set_right(Node(80))
|
|
|
|
|
|
|
|
|
|
|
|
# Complexity: Theta(n)
|
|
|
|
def in_order_walk(t):
|
|
|
|
if t is not None:
|
|
|
|
in_order_walk(t.left)
|
|
|
|
print(t.key, end=' ')
|
|
|
|
in_order_walk(t.right)
|
|
|
|
|
|
|
|
|
|
|
|
# Complexity: Theta(n)
|
|
|
|
def reverse_walk(t):
|
|
|
|
if t is not None:
|
|
|
|
reverse_walk(t.right)
|
|
|
|
print(t.key, end=' ')
|
|
|
|
reverse_walk(t.left)
|
|
|
|
|
|
|
|
|
|
|
|
# Complexity (worst): Theta(n)
|
|
|
|
def search(tree, k):
|
2019-05-08 15:45:03 +00:00
|
|
|
if tree is None:
|
|
|
|
return None
|
|
|
|
elif tree.key == k:
|
|
|
|
return tree
|
|
|
|
elif k < tree.key:
|
|
|
|
return search(tree.left, k)
|
|
|
|
else:
|
|
|
|
return search(tree.right, k)
|
2019-04-23 11:37:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Complexity (worst): Theta(n)
|
|
|
|
def min(t):
|
|
|
|
if t is None:
|
|
|
|
return None
|
|
|
|
while t.left is not None:
|
|
|
|
t = t.left
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
|
|
# Complexity (worst): Theta(n)
|
|
|
|
def max(t):
|
|
|
|
if t is None:
|
|
|
|
return None
|
|
|
|
while t.right is not None:
|
|
|
|
t = t.right
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
|
|
def successor(t):
|
|
|
|
if t.right is not None:
|
|
|
|
return min(t.right)
|
|
|
|
while t.parent is not None:
|
|
|
|
if t.parent.left == t:
|
|
|
|
return t.parent
|
|
|
|
else:
|
|
|
|
t = t.parent
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def predecessor(t):
|
|
|
|
if t.left is not None:
|
|
|
|
return max(t.left)
|
|
|
|
while t is not None:
|
|
|
|
if t.parent.right == t:
|
|
|
|
return t.parent
|
|
|
|
else:
|
|
|
|
t = t.parent
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def insert(t, k):
|
2019-05-08 15:45:03 +00:00
|
|
|
insert_node(t, Node(k))
|
|
|
|
|
|
|
|
|
|
|
|
def insert_node(t, node):
|
|
|
|
if node.key < t.key:
|
|
|
|
if t.left is None:
|
|
|
|
t.set_left(node)
|
|
|
|
else:
|
|
|
|
insert_node(t.left, node)
|
2019-04-23 11:37:26 +00:00
|
|
|
else:
|
2019-05-08 15:45:03 +00:00
|
|
|
if t.right is None:
|
|
|
|
t.set_right(node)
|
|
|
|
else:
|
|
|
|
insert_node(t.right, node)
|
|
|
|
|
2019-04-23 11:37:26 +00:00
|
|
|
|
|
|
|
def right_rotate(x):
|
|
|
|
# assume x is not None
|
|
|
|
# assume x.left is not None
|
|
|
|
t = x.left
|
|
|
|
x.left = t.right
|
|
|
|
t.right = x
|
|
|
|
return t
|
|
|
|
|
2019-05-08 15:45:03 +00:00
|
|
|
|
2019-04-23 11:37:26 +00:00
|
|
|
def left_rotate(x):
|
|
|
|
# assume x is not None
|
|
|
|
# assume x.right is not None
|
|
|
|
t = x.right
|
|
|
|
x.right = t.left
|
|
|
|
t.left = x
|
|
|
|
return t
|
|
|
|
|
2019-05-08 15:45:03 +00:00
|
|
|
|
2019-04-23 11:37:26 +00:00
|
|
|
def root_insert(t, k):
|
|
|
|
if t is None:
|
|
|
|
return Node(k)
|
|
|
|
if k > t.key:
|
|
|
|
t.set_right(root_insert(t.right, k))
|
|
|
|
return left_rotate(t)
|
|
|
|
else:
|
|
|
|
t.set_left(root_insert(t.left, k))
|
|
|
|
return right_rotate(t)
|
|
|
|
|
2019-05-08 15:45:03 +00:00
|
|
|
|
|
|
|
def unlink_me(node, to_link):
|
|
|
|
if node.parent == None:
|
|
|
|
node.key = to_link.key
|
|
|
|
node.left = to_link.left
|
|
|
|
node.right = to_link.right
|
|
|
|
elif node.parent.left == node:
|
|
|
|
node.parent.left = to_link
|
|
|
|
else:
|
|
|
|
node.parent.right = to_link
|
|
|
|
|
|
|
|
|
|
|
|
def delete(t, k):
|
|
|
|
to_delete = search(t, k)
|
|
|
|
if to_delete is None:
|
|
|
|
return
|
|
|
|
elif to_delete.left is None:
|
|
|
|
unlink_me(to_delete, to_delete.right)
|
|
|
|
elif to_delete.right is None:
|
|
|
|
unlink_me(to_delete, to_delete.left)
|
|
|
|
else:
|
|
|
|
if abs(to_delete.left.key - to_delete.key) < abs(to_delete.right.key -
|
|
|
|
to_delete.key):
|
|
|
|
unlink_me(to_delete, to_delete.left)
|
|
|
|
insert_node(to_delete.left, to_delete.right)
|
|
|
|
else:
|
|
|
|
unlink_me(to_delete, to_delete.right)
|
|
|
|
insert_node(to_delete.right, to_delete.left)
|
|
|
|
|
|
|
|
|
2019-04-23 11:37:26 +00:00
|
|
|
###############################################################################
|
|
|
|
# Code for printing trees, ignore this
|
|
|
|
|
|
|
|
|
|
|
|
class Canvas:
|
|
|
|
def __init__(self, width):
|
|
|
|
self.line_width = width
|
|
|
|
self.canvas = []
|
|
|
|
|
|
|
|
def put_char(self, x, y, c):
|
|
|
|
if x < self.line_width:
|
|
|
|
pos = y * self.line_width + x
|
|
|
|
l = len(self.canvas)
|
|
|
|
if pos < l:
|
|
|
|
self.canvas[pos] = c
|
|
|
|
else:
|
|
|
|
self.canvas[l:] = [' '] * (pos - l)
|
|
|
|
self.canvas.append(c)
|
|
|
|
|
|
|
|
def print_out(self):
|
|
|
|
i = 0
|
|
|
|
for c in self.canvas:
|
|
|
|
sys.stdout.write(c)
|
|
|
|
i = i + 1
|
|
|
|
if i % self.line_width == 0:
|
|
|
|
sys.stdout.write('\n')
|
|
|
|
if i % self.line_width != 0:
|
|
|
|
sys.stdout.write('\n')
|
|
|
|
|
|
|
|
|
|
|
|
def print_binary_r(t, x, y, canvas):
|
|
|
|
max_y = y
|
|
|
|
if t.left is not None:
|
|
|
|
x, max_y, lx, rx = print_binary_r(t.left, x, y + 2, canvas)
|
|
|
|
x = x + 1
|
|
|
|
for i in range(rx, x):
|
|
|
|
canvas.put_char(i, y + 1, '/')
|
|
|
|
|
|
|
|
middle_l = x
|
|
|
|
for c in str(t.key):
|
|
|
|
canvas.put_char(x, y, c)
|
|
|
|
x = x + 1
|
|
|
|
middle_r = x
|
|
|
|
|
|
|
|
if t.right is not None:
|
|
|
|
canvas.put_char(x, y + 1, '\\')
|
|
|
|
x = x + 1
|
|
|
|
x0, max_y2, lx, rx = print_binary_r(t.right, x, y + 2, canvas)
|
|
|
|
if max_y2 > max_y:
|
|
|
|
max_y = max_y2
|
|
|
|
for i in range(x, lx):
|
|
|
|
canvas.put_char(i, y + 1, '\\')
|
|
|
|
x = x0
|
|
|
|
|
|
|
|
return (x, max_y, middle_l, middle_r)
|
|
|
|
|
|
|
|
|
|
|
|
def print_tree(t):
|
|
|
|
print_w(t, 80)
|
|
|
|
|
|
|
|
|
|
|
|
def print_w(t, width):
|
|
|
|
canvas = Canvas(width)
|
|
|
|
print_binary_r(t, 0, 0, canvas)
|
|
|
|
canvas.print_out()
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2019-05-08 15:45:03 +00:00
|
|
|
args = [x for x in sys.argv[1:]]
|
|
|
|
T = Node(int(args[0]))
|
|
|
|
for i in range(1, len(args)):
|
|
|
|
if args[i] == '|':
|
|
|
|
break
|
|
|
|
print_tree(T)
|
|
|
|
print("\nInsert " + str(args[i]) + ":")
|
|
|
|
insert(T, int(args[i]))
|
|
|
|
for i in range(i+1, len(args)):
|
|
|
|
print_tree(T)
|
|
|
|
print("\nDelete " + str(args[i]) + ":")
|
|
|
|
delete(T, int(args[i]))
|
|
|
|
print_tree(T)
|
|
|
|
#print(tree.left.right.right.key)
|
|
|
|
#print(successor(tree.left.right.right).key)
|
|
|
|
#print(predecessor(tree.left.right.right).key)
|
2019-04-09 11:38:46 +00:00
|
|
|
|