Fixed GA3 again
This commit is contained in:
parent
4bca4b25ac
commit
d37f05664d
4 changed files with 507 additions and 130 deletions
BIN
GA3/ga3.pdf
BIN
GA3/ga3.pdf
Binary file not shown.
391
GA3/ga3.tex
391
GA3/ga3.tex
|
@ -222,6 +222,124 @@ Delete 12:
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
The following printout was obtained by running the following BST implementation.with the following command:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
./tree.py 12 6 1 7 4 11 15 9 5 13 8 14 3 10 2 \| 6 2 12
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
\begin{lstlisting}[caption=BST implementation, language=python]
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# $\textbf{\color{red}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
|
||||||
|
|
||||||
|
|
||||||
|
def search(tree, k):
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def insert(t, k):
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
if t.right is None:
|
||||||
|
t.set_right(node)
|
||||||
|
else:
|
||||||
|
insert_node(t.right, node)
|
||||||
|
|
||||||
|
|
||||||
|
def root_insert(t, k):
|
||||||
|
if t is None:
|
||||||
|
return k
|
||||||
|
if k.key > 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)
|
||||||
|
|
||||||
|
|
||||||
|
def unlink_me(node, to_link):
|
||||||
|
if node.parent == None:
|
||||||
|
tr = node
|
||||||
|
node.key = to_link.key
|
||||||
|
node.left = to_link.left
|
||||||
|
node.right = to_link.right
|
||||||
|
return node
|
||||||
|
elif node.parent.left == node:
|
||||||
|
node.parent.left = to_link
|
||||||
|
return to_link
|
||||||
|
else:
|
||||||
|
node.parent.right = to_link
|
||||||
|
return 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):
|
||||||
|
ins = to_delete.right
|
||||||
|
new_branch = unlink_me(to_delete, to_delete.left)
|
||||||
|
insert_node(new_branch, ins)
|
||||||
|
else:
|
||||||
|
ins = to_delete.left
|
||||||
|
new_branch = unlink_me(to_delete, to_delete.right)
|
||||||
|
insert_node(new_branch, ins)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
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)
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
\section{Exercise 2}
|
\section{Exercise 2}
|
||||||
|
|
||||||
\subsection{Point A}
|
\subsection{Point A}
|
||||||
|
@ -262,22 +380,22 @@ Insert 11:
|
||||||
4R 7R 12R
|
4R 7R 12R
|
||||||
|
|
||||||
Insert 15:
|
Insert 15:
|
||||||
11B
|
6B
|
||||||
//// \
|
//// \\\\
|
||||||
6R 12B
|
1B 11R
|
||||||
//// \ \
|
\ / \
|
||||||
1B 7B 15R
|
4R 7B 12B
|
||||||
\
|
\
|
||||||
4R
|
15R
|
||||||
|
|
||||||
Insert 9:
|
Insert 9:
|
||||||
11B
|
6B
|
||||||
/////// \
|
//// \\\\\\\
|
||||||
6R 12B
|
1B 11R
|
||||||
//// \ \
|
\ //// \
|
||||||
1B 7B 15R
|
4R 7B 12B
|
||||||
\ \
|
\ \
|
||||||
4R 9R
|
9R 15R
|
||||||
|
|
||||||
Insert 5:
|
Insert 5:
|
||||||
6B
|
6B
|
||||||
|
@ -289,82 +407,216 @@ Insert 5:
|
||||||
9R 15R
|
9R 15R
|
||||||
|
|
||||||
Insert 13:
|
Insert 13:
|
||||||
11B
|
6B
|
||||||
/////// \\\\\
|
//// \\\\\\\
|
||||||
6R 13B
|
4B 11R
|
||||||
//// \ / \
|
/ \ //// \\\\\
|
||||||
4B 7B 12R 15R
|
1R 5R 7B 13B
|
||||||
/ \ \
|
\ / \
|
||||||
1R 5R 9R
|
9R 12R 15R
|
||||||
|
|
||||||
Insert 8:
|
Insert 8:
|
||||||
8B
|
6B
|
||||||
//// \\\\
|
//// \\\\\\\\\\
|
||||||
6R 11R
|
4B 11R
|
||||||
//// \ / \\\\\
|
/ \ //// \\\\\
|
||||||
4B 7R 9R 13B
|
1R 5R 8B 13B
|
||||||
/ \ / \
|
/ \ / \
|
||||||
1R 5R 12R 15R
|
7R 9R 12R 15R
|
||||||
|
|
||||||
Insert 14:
|
Insert 14:
|
||||||
8B
|
11B
|
||||||
//// \\\\
|
////////// \\\\\
|
||||||
6B 11B
|
6R 13R
|
||||||
//// \ / \\\\\
|
//// \\\\ / \\\\\
|
||||||
4B 7R 9B 13B
|
4B 8B 12B 15B
|
||||||
/ \ / \\\\\
|
/ \ / \ /
|
||||||
1R 5R 12B 15B
|
1R 5R 7R 9R 14R
|
||||||
/
|
|
||||||
14R
|
|
||||||
|
|
||||||
Insert 3:
|
Insert 3:
|
||||||
6B
|
11B
|
||||||
//// \\\\
|
////////// \\\\\
|
||||||
4B 8R
|
6B 13B
|
||||||
//// \ / \\\\
|
//// \\\\ / \\\\\
|
||||||
1B 5B 7B 11B
|
4R 8B 12B 15B
|
||||||
\ / \\\\\
|
//// \ / \ /
|
||||||
3R 9B 13B
|
1B 5B 7R 9R 14R
|
||||||
/ \\\\\
|
\
|
||||||
12B 15B
|
3R
|
||||||
/
|
|
||||||
14R
|
|
||||||
|
|
||||||
Insert 10:
|
Insert 10:
|
||||||
6B
|
11B
|
||||||
//// \\\\
|
////////////// \\\\\
|
||||||
4B 8R
|
6B 13B
|
||||||
//// \ / \\\\\\\\
|
//// \\\\ / \\\\\
|
||||||
1B 5B 7B 11B
|
4R 8R 12B 15B
|
||||||
\ ///// \\\\\
|
//// \ / \ /
|
||||||
3R 9B 13B
|
1B 5B 7B 9B 14R
|
||||||
\ / \\\\\
|
\ \
|
||||||
10R 12B 15B
|
3R 10R
|
||||||
/
|
|
||||||
14R
|
|
||||||
|
|
||||||
Insert 2:
|
Insert 2:
|
||||||
6B
|
11B
|
||||||
//// \\\\
|
////////////// \\\\\
|
||||||
4B 8R
|
6B 13B
|
||||||
//// \ / \\\\\\\\
|
//// \\\\ / \\\\\
|
||||||
2B 5B 7B 11B
|
4R 8R 12B 15B
|
||||||
/ \ ///// \\\\\
|
//// \ / \ /
|
||||||
1R 3R 9B 13B
|
2B 5B 7B 9B 14R
|
||||||
\ / \\\\\
|
/ \ \
|
||||||
10R 12B 15B
|
1R 3R 10R
|
||||||
/
|
|
||||||
14R
|
|
||||||
\end{verbatim}%
|
\end{verbatim}%
|
||||||
}%
|
}%
|
||||||
%
|
%
|
||||||
Assume every empty branch has as a child a black leaf node.
|
Assume every empty branch has as a child a black leaf node.
|
||||||
|
|
||||||
|
The following printout was generated by this red-black tree implementation in python with the following command:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
python3 redblack.py 12 6 1 7 4 11 15 9 5 13 8 14 3 10 2
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
\begin{lstlisting}[caption=Red-black tree implementation, language=python]
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# $\textbf{\color{red}vim}$: set ts=2 sw=2 et tw=80:
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class Tree:
|
||||||
|
def __init__(self, root):
|
||||||
|
self.root = root
|
||||||
|
root.parent = self
|
||||||
|
|
||||||
|
def set_root(self, root):
|
||||||
|
self.root = root
|
||||||
|
root.parent = self
|
||||||
|
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
def __init__(self, k):
|
||||||
|
self.key = k
|
||||||
|
self.isBlack = True
|
||||||
|
self.left = None
|
||||||
|
self.right = None
|
||||||
|
self.parent = None
|
||||||
|
|
||||||
|
def set_left(self, kNode):
|
||||||
|
if kNode is not None:
|
||||||
|
kNode.parent = self
|
||||||
|
self.left = kNode
|
||||||
|
|
||||||
|
def set_right(self, kNode):
|
||||||
|
if kNode is not None:
|
||||||
|
kNode.parent = self
|
||||||
|
self.right = kNode
|
||||||
|
|
||||||
|
|
||||||
|
def is_black(node):
|
||||||
|
return node is None or node.isBlack
|
||||||
|
|
||||||
|
|
||||||
|
def insert(tree, node):
|
||||||
|
y = None
|
||||||
|
x = tree
|
||||||
|
# Imperatively find place to insert node
|
||||||
|
while x is not None:
|
||||||
|
y = x
|
||||||
|
if node.key < x.key:
|
||||||
|
x = x.left
|
||||||
|
else:
|
||||||
|
x = x.right
|
||||||
|
|
||||||
|
node.parent = y
|
||||||
|
if y is None:
|
||||||
|
tree = node
|
||||||
|
elif node.key < y.key:
|
||||||
|
y.left = node
|
||||||
|
else:
|
||||||
|
y.right = node
|
||||||
|
node.isBlack = False
|
||||||
|
insert_fixup(tree, node)
|
||||||
|
|
||||||
|
|
||||||
|
def sibling(node):
|
||||||
|
if node.parent.left is node:
|
||||||
|
return node.parent.right
|
||||||
|
else:
|
||||||
|
return node.parent.left
|
||||||
|
|
||||||
|
|
||||||
|
def uncle(node):
|
||||||
|
return sibling(node.parent)
|
||||||
|
|
||||||
|
|
||||||
|
def right_rotate(x):
|
||||||
|
p = x.parent
|
||||||
|
t = x.left
|
||||||
|
x.set_left(t.right)
|
||||||
|
t.set_right(x)
|
||||||
|
if isinstance(p, Tree):
|
||||||
|
p.set_root(t)
|
||||||
|
elif p.left is x:
|
||||||
|
p.set_left(t)
|
||||||
|
else:
|
||||||
|
p.set_right(t)
|
||||||
|
|
||||||
|
|
||||||
|
def left_rotate(x):
|
||||||
|
p = x.parent
|
||||||
|
t = x.right
|
||||||
|
x.set_right(t.left)
|
||||||
|
t.set_left(x)
|
||||||
|
if isinstance(p, Tree):
|
||||||
|
p.set_root(t)
|
||||||
|
elif p.left is x:
|
||||||
|
p.set_left(t)
|
||||||
|
else:
|
||||||
|
p.set_right(t)
|
||||||
|
|
||||||
|
|
||||||
|
def insert_fixup(tree, node):
|
||||||
|
if isinstance(node.parent, Tree): # if root
|
||||||
|
node.isBlack = True
|
||||||
|
elif is_black(node.parent):
|
||||||
|
# no fixup needed
|
||||||
|
pass
|
||||||
|
elif not isinstance(node.parent.parent, Tree) and not is_black(uncle(node)):
|
||||||
|
node.parent.parent.isBlack = False
|
||||||
|
node.parent.isBlack = True
|
||||||
|
if sibling(node.parent) is not None:
|
||||||
|
sibling(node.parent).isBlack = True
|
||||||
|
insert_fixup(tree, node.parent.parent)
|
||||||
|
else:
|
||||||
|
if node.parent.parent.left is node.parent:
|
||||||
|
if node.parent.right is node:
|
||||||
|
left_rotate(node.parent)
|
||||||
|
node = node.left
|
||||||
|
right_rotate(node.parent.parent)
|
||||||
|
else:
|
||||||
|
if node.parent.left is node:
|
||||||
|
right_rotate(node.parent)
|
||||||
|
node = node.right
|
||||||
|
left_rotate(node.parent.parent)
|
||||||
|
node.parent.isBlack = True
|
||||||
|
if sibling(node) is not None:
|
||||||
|
sibling(node).isBlack = False
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = [x for x in sys.argv[1:]]
|
||||||
|
T = Tree(Node(int(args[0])))
|
||||||
|
for i in range(1, len(args)):
|
||||||
|
print_tree(T.root)
|
||||||
|
print("\nInsert " + str(args[i]) + ":")
|
||||||
|
insert(T.root, Node(int(args[i])))
|
||||||
|
print_tree(T.root)
|
||||||
|
\end{lstlisting}
|
||||||
\subsection{Point B}
|
\subsection{Point B}
|
||||||
|
|
||||||
A red-black tree of n distinct elements has an height between $\log(n)$
|
A red-black tree of n distinct elements has an height between $\log(n)$
|
||||||
and $2\log(n)$ thanks to the red-black tree invariant. The worst-case insertion
|
and $2\log(n)$ (as professor Carzaniga said in class) thanks to the red-black
|
||||||
complexity is $\log(n)$ since finding the right place to insert is as complex as
|
tree invariant. The worst-case insertion complexity is $\log(n)$ since
|
||||||
|
finding the right place to insert is as complex as
|
||||||
a regular tree (i.e. logarithmic) and the ``fixup'' operation is logarithmic as
|
a regular tree (i.e. logarithmic) and the ``fixup'' operation is logarithmic as
|
||||||
well (the tree traversal is logarithmic while operations in each iteration are constant).
|
well (the tree traversal is logarithmic while operations in each iteration are constant).
|
||||||
In asymptotic terms, the uneven height of leaves in the tree does not make a difference
|
In asymptotic terms, the uneven height of leaves in the tree does not make a difference
|
||||||
|
@ -393,6 +645,7 @@ FUNCTION JOIN-INTERVALS(X)
|
||||||
if c == 0:
|
if c == 0:
|
||||||
X[2 * n + 1] $\gets$ start
|
X[2 * n + 1] $\gets$ start
|
||||||
X[2 * n + 2] $\gets$ X[i][1]
|
X[2 * n + 2] $\gets$ X[i][1]
|
||||||
|
if i < X.length:
|
||||||
start $\gets$ X[i+1][1]
|
start $\gets$ X[i+1][1]
|
||||||
n $\gets$ n + 1
|
n $\gets$ n + 1
|
||||||
X.length $\gets$ 2 * n
|
X.length $\gets$ 2 * n
|
||||||
|
|
|
@ -107,14 +107,12 @@ def insert_fixup(tree, node):
|
||||||
elif is_black(node.parent):
|
elif is_black(node.parent):
|
||||||
# no fixup needed
|
# no fixup needed
|
||||||
pass
|
pass
|
||||||
elif isinstance(node.parent.parent, Tree):
|
elif not isinstance(node.parent.parent, Tree) and not is_black(uncle(node)):
|
||||||
node.parent.isBlack = True
|
|
||||||
elif not is_black(uncle(node)):
|
|
||||||
node.parent.parent.isBlack = False
|
node.parent.parent.isBlack = False
|
||||||
node.parent.isBlack = True
|
node.parent.isBlack = True
|
||||||
if sibling(node.parent) is not None:
|
if sibling(node.parent) is not None:
|
||||||
sibling(node.parent).isBlack = True
|
sibling(node.parent).isBlack = True
|
||||||
insert_fixup(tree, node.parent)
|
insert_fixup(tree, node.parent.parent)
|
||||||
else:
|
else:
|
||||||
if node.parent.parent.left is node.parent:
|
if node.parent.parent.left is node.parent:
|
||||||
if node.parent.right is node:
|
if node.parent.right is node:
|
||||||
|
@ -129,59 +127,6 @@ def insert_fixup(tree, node):
|
||||||
node.parent.isBlack = True
|
node.parent.isBlack = True
|
||||||
if sibling(node) is not None:
|
if sibling(node) is not None:
|
||||||
sibling(node).isBlack = False
|
sibling(node).isBlack = False
|
||||||
insert_fixup(tree, node.parent)
|
|
||||||
|
|
||||||
|
|
||||||
# Complexity (worst): Theta(n)
|
|
||||||
def search(tree, k):
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Code for printing trees, ignore this
|
# Code for printing trees, ignore this
|
179
GA3/tree.py
Executable file
179
GA3/tree.py
Executable file
|
@ -0,0 +1,179 @@
|
||||||
|
#!/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
|
||||||
|
|
||||||
|
|
||||||
|
def search(tree, k):
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
def insert(t, k):
|
||||||
|
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)
|
||||||
|
else:
|
||||||
|
if t.right is None:
|
||||||
|
t.set_right(node)
|
||||||
|
else:
|
||||||
|
insert_node(t.right, node)
|
||||||
|
|
||||||
|
|
||||||
|
def root_insert(t, k):
|
||||||
|
if t is None:
|
||||||
|
return k
|
||||||
|
if k.key > 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)
|
||||||
|
|
||||||
|
|
||||||
|
def unlink_me(node, to_link):
|
||||||
|
if node.parent == None:
|
||||||
|
tr = node
|
||||||
|
node.key = to_link.key
|
||||||
|
node.left = to_link.left
|
||||||
|
node.right = to_link.right
|
||||||
|
return node
|
||||||
|
elif node.parent.left == node:
|
||||||
|
node.parent.left = to_link
|
||||||
|
return to_link
|
||||||
|
else:
|
||||||
|
node.parent.right = to_link
|
||||||
|
return 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):
|
||||||
|
ins = to_delete.right
|
||||||
|
new_branch = unlink_me(to_delete, to_delete.left)
|
||||||
|
insert_node(new_branch, ins)
|
||||||
|
else:
|
||||||
|
ins = to_delete.left
|
||||||
|
new_branch = unlink_me(to_delete, to_delete.right)
|
||||||
|
insert_node(new_branch, ins)
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 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__":
|
||||||
|
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)
|
||||||
|
|
Reference in a new issue