Skip to content

Implement Fibonacci Heap data structure #9239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 32 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8c3b8b3
Fix #9095 : Implement Fibonacci Heap data structure
Dhruv127 Oct 1, 2023
23a39fc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
ef2c1ee
Add missing doctests
Dhruv127 Oct 1, 2023
32aa637
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
06fb015
Ensured proper type annotations and removed unused imports. - Fixed p…
Dhruv127 Oct 1, 2023
dd6acd5
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
f0ddb4e
Fixed line length issues for better readability. - Removed future imp…
Dhruv127 Oct 1, 2023
46a7191
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
5da268b
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
8cd50d4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
044afb0
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
774ba12
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
fee3f04
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
053b55f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
f969985
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
aef5090
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
4b16251
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
b554801
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
908891c
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
f08e189
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
e67a442
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
dab519f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
11d84fe
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
d864b47
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
9fc373d
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
0a897c3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
b2df7cd
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
e421610
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
5076ab4
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
757daaf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
bb257cb
Update fibonacci_heap.py
Dhruv127 Oct 1, 2023
160f525
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 144 additions & 0 deletions data_structures/heap/fibonacci_heap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Implementation of a Fibonacci Heap based on the concepts described in "Introduction to Algorithms" by Cormen, Leiserson, Rivest, and Stein.
# Reference: https://en.wikipedia.org/wiki/Fibonacci_heap

from __future__ import annotations
from collections.abc import Iterable, Iterator
from typing import Any, Generic, TypeVar

T = TypeVar("T", bound=int)


class FibonacciNode(Generic[T]):
def __init__(self, key: T) -> None:
"""
Create a new FibonacciNode with the given key.

Args:
key (T): The key value associated with the node.
"""
self.key: T = key
self.degree: int = 0
self.parent: FibonacciNode[T] | None = None
self.child: FibonacciNode[T] | None = None
self.is_marked: bool = False
self.next: FibonacciNode[T] = self
self.prev: FibonacciNode[T] = self


class FibonacciHeap(Generic[T]):
def __init__(self) -> None:
"""
Create a new Fibonacci Heap.

The Fibonacci Heap is initialized as an empty heap.
"""
self.min_node: FibonacciNode[T] | None = None
self.num_nodes: int = 0

def insert(self, key: T) -> None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/heap/fibonacci_heap.py, please provide doctest for the function insert

"""
Insert a new node with the given key into the Fibonacci Heap.

Args:
key (T): The key value to insert.
"""
new_node = FibonacciNode(key)
if self.min_node is None:
self.min_node = new_node
else:
self._link_nodes(self.min_node, new_node)
if key < self.min_node.key:
self.min_node = new_node
self.num_nodes += 1

def _link_nodes(self, min_node: FibonacciNode[T], new_node: FibonacciNode[T]) -> None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/heap/fibonacci_heap.py, please provide doctest for the function _link_nodes

"""
Link two nodes together in the Fibonacci Heap.

Args:
min_node (FibonacciNode): The minimum node.
new_node (FibonacciNode): The new node to be linked.
"""
new_node.next = min_node.next
min_node.next = new_node
new_node.prev = min_node
new_node.next.prev = new_node

def _consolidate(self) -> None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/heap/fibonacci_heap.py, please provide doctest for the function _consolidate

"""
Consolidate the heap by combining trees with the same degree.

This is an internal method used to maintain the Fibonacci Heap's properties.
"""
max_degree = int(self.num_nodes ** 0.5) + 1
degree_buckets: list[FibonacciNode[T] | None] = [None] * max_degree

current_node = self.min_node
nodes_to_visit = [current_node]
while True:
current_node = current_node.next
if current_node == self.min_node:
break
nodes_to_visit.append(current_node)

for node in nodes_to_visit:
degree = node.degree
while degree_buckets[degree]:
other = degree_buckets[degree]
if node.key > other.key:
node, other = other, node
self._link_nodes(node, other)
degree_buckets[degree] = None
degree += 1
degree_buckets[degree] = node

self.min_node = None
for node in degree_buckets:
if node:
if self.min_node is None or node.key < self.min_node.key:
self.min_node = node

def extract_min(self) -> T | None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/heap/fibonacci_heap.py, please provide doctest for the function extract_min

"""
Extract the minimum element from the Fibonacci Heap.

Returns:
T | None: The minimum element, or None if the heap is empty.
"""
min_node = self.min_node
if min_node:
if min_node.child:
child = min_node.child
while True:
next_child = child.next
child.prev = min_node.prev
child.next = min_node.next
min_node.prev.next = child
min_node.next.prev = child
min_node.child = None
if next_child == min_node.child:
break
child = next_child
self._remove_node(min_node)
if min_node == min_node.next:
self.min_node = None
else:
self.min_node = min_node.next
self._consolidate()
self.num_nodes -= 1
return min_node.key if min_node else None

def _remove_node(self, node: FibonacciNode[T]) -> None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file data_structures/heap/fibonacci_heap.py, please provide doctest for the function _remove_node

"""
Remove a node from the doubly linked list of nodes.

Args:
node (FibonacciNode): The node to remove.
"""
node.prev.next = node.next
node.next.prev = node.prev

if __name__ == "__main__":
import doctest
doctest.testmod()