Skip to content

Commit 1b296aa

Browse files
committed
Added Fibonacci_Heap for DSA
1 parent 596d934 commit 1b296aa

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
class FibonacciNode:
2+
def __init__(self, key):
3+
self.key = key
4+
self.children = []
5+
self.marked = False
6+
self.degree = 0
7+
self.parent = None
8+
9+
class FibonacciHeap:
10+
def __init__(self):
11+
self.trees = []
12+
self.least = None
13+
self.count = 0
14+
15+
def insert(self, key):
16+
new_node = FibonacciNode(key)
17+
self.trees.append(new_node)
18+
self.count += 1
19+
if self.least is None or key < self.least.key:
20+
self.least = new_node
21+
22+
def extract_min(self):
23+
if self.count == 0:
24+
raise ValueError("Heap is empty")
25+
26+
min_node = self.least
27+
self.trees.remove(min_node)
28+
29+
for child in min_node.children:
30+
child.parent = None
31+
self.trees.append(child)
32+
33+
self.count -= 1
34+
35+
if self.least is min_node:
36+
self.least = None
37+
for node in self.trees:
38+
if self.least is None or node.key < self.least.key:
39+
self.least = node
40+
41+
self.consolidate()
42+
return min_node.key
43+
44+
def consolidate(self):
45+
degree_counts = [None] * (2 * len(self.trees))
46+
47+
for node in self.trees[:]:
48+
degree = node.degree
49+
while degree_counts[degree] is not None:
50+
other_node = degree_counts[degree]
51+
if node.key > other_node.key:
52+
node, other_node = other_node, node # Swap nodes
53+
self.link(other_node, node)
54+
degree_counts[degree] = None
55+
degree += 1
56+
degree_counts[degree] = node
57+
58+
self.trees = [node for node in degree_counts if node is not None]
59+
60+
def link(self, node1, node2):
61+
self.trees.remove(node2)
62+
node1.children.append(node2)
63+
node2.parent = node1
64+
node1.degree += 1
65+
node2.marked = False
66+
67+
def decrease_key(self, node, new_key):
68+
if new_key > node.key:
69+
raise ValueError("New key must be less than or equal to old key")
70+
71+
node.key = new_key
72+
73+
if node == self.least:
74+
self.update_least()
75+
76+
parent = node.parent
77+
if parent is not None and node.key < parent.key:
78+
self.cut(node, parent)
79+
self.cascading_cut(parent)
80+
81+
def cut(self, node, parent):
82+
parent.children.remove(node)
83+
parent.degree -= 1
84+
self.trees.append(node)
85+
node.parent = None
86+
node.marked = False
87+
88+
def cascading_cut(self, node):
89+
parent = node.parent
90+
if parent is not None:
91+
if not node.marked:
92+
node.marked = True
93+
else:
94+
self.cut(node, parent)
95+
self.cascading_cut(parent)
96+
97+
def update_least(self):
98+
self.least = None
99+
for node in self.trees:
100+
if self.least is None or node.key < self.least.key:
101+
self.least = node

0 commit comments

Comments
 (0)