Stuff before easter break

This commit is contained in:
Claudio Maggioni 2019-04-23 13:37:26 +02:00
parent d724db3cca
commit 6958a25712
3 changed files with 270 additions and 33 deletions

View file

@ -246,15 +246,13 @@ insertion and search.
## Growing a *chained hash table* ## Growing a *chained hash table*
In order to grow a table, a new table must be created. The hash function (or it In order to grow a table, a new table must be created. The hash function (or
s its range parameters) must be changed as well.
range parameters) must be changed as well.
### Rehashing ### Rehashing
*Rehashing* is the process of putting all the elements of the old table in the *Rehashing* is the process of putting all the elements of the old table in the
new new table according to the new hash function. The complexity is O(n), since
table according to the new hash function. The complexity is O(n), since
`Chained-hash-insert` is constant. `Chained-hash-insert` is constant.
### Growing the table every time ### Growing the table every time
@ -279,4 +277,40 @@ that has ...)
- `Tree-Search(T, k)` returns if key K is in the tree T; - `Tree-Search(T, k)` returns if key K is in the tree T;
- `Tree-Minimum(T)` finds the smallest element in the tree; - `Tree-Minimum(T)` finds the smallest element in the tree;
- `Tree-Maximum(T)` finds the biggest element in the tree; - `Tree-Maximum(T)` finds the biggest element in the tree;
- `Tree-successor(T, k)` `Tree-predecessor(T, k) - `Tree-successor(T, k)` and `Tree-predecessor(T, k)` find the next and
previous position in the tree
## Height of a tree
The height of a tree is the maximum number of edges traversed from parent to
child in order to reach a leaf from the root of the tree.
## Rotation
```
b
/ \
a \
/ \ \
/ \ \
k <= a a <= k <= b k >= b
```
```
a
/ \
/ b
/ / \
/ / \
k <= a a <= k <= b k >= b
```
# Red-Black trees
1. Every node has a color: red or black
2. The root is black
3. Every NULL leaf node is black
4. If a node is red, both of its children are black
5. The black height is the same for every branch in the tree
A red node is a way to strech the tree, but the

View file

@ -1,37 +1,40 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim: set ts=2 sw=2 et tw=80:
import sys import sys
import random import random
def partition(A, begin, end): def partition(A, begin, end):
v_i = random.randrange(begin, end) v_i = random.randrange(begin, end)
v = A[v_i] v = A[v_i]
A[v_i], A[end-1] = A[end-1], A[v_i] A[v_i], A[end - 1] = A[end - 1], A[v_i]
i = begin i = begin
j = end - 2 j = end - 2
while j >= i: while j >= i:
if A[j] > v: if A[j] > v:
j = j - 1 j = j - 1
elif A[i] <= v: elif A[i] <= v:
i = i + 1 i = i + 1
else: else:
A[i], A[j] = A[j], A[i] A[i], A[j] = A[j], A[i]
j = j - 1 j = j - 1
i = i + 1 i = i + 1
A[i], A[end-1] = A[end-1], A[i] A[i], A[end - 1] = A[end - 1], A[i]
return i return i
def quicksort(A, begin, end): def quicksort(A, begin, end):
if begin < end - 1: if begin < end - 1:
i = partition(A, begin, end) i = partition(A, begin, end)
print(A[begin:i], A[i], A[i+1:end]) print(A[begin:i], A[i], A[i + 1:end])
quicksort(A, begin, i) quicksort(A, begin, i)
quicksort(A, i+1, end) quicksort(A, i + 1, end)
print(A[begin:i], A[i], A[i+1:end]) print(A[begin:i], A[i], A[i + 1:end])
if __name__ == "__main__": if __name__ == "__main__":
args = [int(x) for x in sys.argv[1:]] args = [int(x) for x in sys.argv[1:]]
print(args) print(args)
quicksort(args, 0, len(args)) quicksort(args, 0, len(args))
print(args) print(args)

200
tree.py
View file

@ -1,10 +1,210 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# vim: set ts=2 sw=2 et tw=80: # vim: set ts=2 sw=2 et tw=80:
import sys
class Node: class Node:
def __init__(self, k): def __init__(self, k):
self.key = k self.key = k
self.left = None self.left = None
self.right = 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)