This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
DSA/tree.py

211 lines
3.9 KiB
Python

#!/usr/bin/env python3
# vim: set ts=2 sw=2 et tw=80:
import sys
class Node:
def __init__(self, k):
self.key = k
self.left = None
self.right = None
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):
pass
# 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):
if t is None:
return Node(k)
if t.key < t.key:
t.set_left(insert(t.left, k))
else:
tree.set_right(insert(t.right, k))
return t
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
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
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)
###############################################################################
# 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__":
print_tree(tree)
in_order_walk(tree)
print()
reverse_walk(tree)
print()
print(tree.left.right.right.key)
print(successor(tree.left.right.right).key)
print(predecessor(tree.left.right.right).key)