Stuff before easter break
This commit is contained in:
parent
d724db3cca
commit
6958a25712
3 changed files with 270 additions and 33 deletions
46
notes.md
46
notes.md
|
@ -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
|
||||||
|
|
57
partition.py
57
partition.py
|
@ -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
200
tree.py
|
@ -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)
|
||||||
|
|
||||||
|
|
Reference in a new issue