-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfibonacci_heap.py
80 lines (65 loc) · 2 KB
/
fibonacci_heap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from collections import deque
class FibNode:
def __init__(self, value):
self.value = value
self.children = []
self.rank = 0
def add_child(self, value):
if self.rank == 0:
self.rank = 1
self.rank += value.rank
self.children.append(value)
def __lt__(self, other):
if not isinstance(other, FibNode):
return self.value < other
return self.value < other.value
def __eq__(self, other):
if not isinstance(other, FibNode):
return self.value == other
return self.value == other.value
class FibHeap:
def __init__(self):
self.root_list = []
self.min = float('inf')
def add_node(self, value):
if value < self.min:
self.min = value
self.root_list.append(value)
def delete_min(self):
min_node = self.min
self.root_list.remove(self.min)
for child in self.min.children:
self.add_node(child)
if not self.root_list:
self.min = None
return min_node
self.min = min(self.root_list)
ranks = {}
# Consolidate trees so that no two trees have the same rank
for root in self.root_list:
if root.rank in ranks:
if ranks[root.rank] != root:
continue
taken_root = ranks[root.rank]
if taken_root < root:
taken_root.add_child(root)
else:
root.add_child(taken_root)
else:
ranks[root.rank] = root
return min_node
fh = FibHeap()
fh.add_node(FibNode(5))
fh.add_node(FibNode(2))
fh.add_node(FibNode(6))
fh.add_node(FibNode(1431))
fh.add_node(FibNode(0))
fh.add_node(FibNode(1))
assert 0 == fh.delete_min()
assert 1 == fh.delete_min()
assert 2 == fh.delete_min()
assert 5 == fh.delete_min()
print(fh.delete_min().value)
print(fh.delete_min().value)
# print(fh.delete_min().value)
# print(fh.delete_min().value)