Skip to content

Commit 93cb2ec

Browse files
committed
refactor(datastructures, heaps): rename packages
1 parent 37b2941 commit 93cb2ec

File tree

17 files changed

+474
-433
lines changed

17 files changed

+474
-433
lines changed
Lines changed: 15 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,15 @@
1-
from abc import ABC, abstractmethod
2-
from typing import Any, List
3-
4-
5-
class Heap(ABC):
6-
"""
7-
Heap abstract class that contains methods for all types of heaps
8-
"""
9-
10-
@abstractmethod
11-
def insert_data(self, data: Any):
12-
"""
13-
Inserts a data value into the heap
14-
"""
15-
raise NotImplementedError("Not yet implemented")
16-
17-
@abstractmethod
18-
def delete(self) -> Any:
19-
"""
20-
Deletes a node from the heap. This is typically the root node. This then performs operations to replace the
21-
deleted node with the appropriate node ensuring that the heap remains complete retaining the property of a heap.
22-
:return: The deleted node
23-
"""
24-
raise NotImplementedError("Delete not yet implemented")
25-
26-
@staticmethod
27-
def get_parent_index(i: int) -> int:
28-
return (i - 1) // 2
29-
30-
@staticmethod
31-
def get_left_child_index(i: int) -> int:
32-
return 2 * i + 1
33-
34-
@staticmethod
35-
def get_right_child_index(i: int) -> int:
36-
return 2 * i + 2
37-
38-
39-
class ArrayBasedHeap(Heap):
40-
"""
41-
Heap datastructure that uses an array as the underlying datastructure to build a heap.
42-
"""
43-
44-
def __init__(self):
45-
super().__init__()
46-
self.data: List[Any] = []
47-
48-
def __len__(self):
49-
return len(self.data)
50-
51-
@property
52-
def root_node(self):
53-
"""
54-
Retrieves the root node of the Heap
55-
:return:
56-
"""
57-
if len(self.data) == 0:
58-
raise Exception("Heap is empty")
59-
return self.data[0]
60-
61-
@property
62-
def last_node(self):
63-
"""
64-
Returns the last node of the heap
65-
:return:
66-
"""
67-
if len(self.data) == 0:
68-
raise Exception("Heap is empty")
69-
return self.data[len(self.data) - 1]
70-
71-
def insert_data(self, data: Any):
72-
"""
73-
Inserts a value into the heap
74-
:param data: element to insert into the heap
75-
"""
76-
raise NotImplementedError("not yet implemented")
77-
78-
def delete(self) -> Any:
79-
"""
80-
Deletes an element from the heap and performs operations to ensure the heap remains complete.
81-
:return: deleted element to from the heap
82-
"""
83-
raise NotImplementedError("not yet implemented")
1+
from datastructures.trees.heaps.heap import Heap
2+
from datastructures.trees.heaps.array_heap import ArrayBasedHeap
3+
from datastructures.trees.heaps.binary import MaxHeap, MinHeap
4+
from datastructures.trees.heaps.fibonacci import FibonacciHeap, FibonacciMaxHeap, FibonacciMinHeap, FibonacciHeapNode
5+
6+
__all__ = [
7+
"Heap",
8+
"ArrayBasedHeap",
9+
"MaxHeap",
10+
"MinHeap",
11+
"FibonacciHeap",
12+
"FibonacciHeapNode",
13+
"FibonacciMaxHeap",
14+
"FibonacciMinHeap"
15+
]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from abc import ABCMeta
2+
from typing import Any, List
3+
from datastructures.trees.heaps.heap import Heap
4+
5+
6+
class ArrayBasedHeap(Heap, metaclass=ABCMeta):
7+
"""
8+
Heap data structure that uses an array as the underlying data structure to build a heap.
9+
"""
10+
11+
def __init__(self):
12+
super().__init__()
13+
self.data: List[Any] = []
14+
15+
def __len__(self):
16+
return len(self.data)
17+
18+
@property
19+
def root_node(self):
20+
"""
21+
Retrieves the root node of the Heap
22+
:return:
23+
"""
24+
if len(self.data) == 0:
25+
raise Exception("Heap is empty")
26+
return self.data[0]
27+
28+
@property
29+
def last_node(self):
30+
"""
31+
Returns the last node of the heap
32+
:return:
33+
"""
34+
if len(self.data) == 0:
35+
raise Exception("Heap is empty")
36+
return self.data[len(self.data) - 1]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from datastructures.trees.heaps.binary.min_heap import MinHeap, MinArrayBasedHeap
2+
from datastructures.trees.heaps.binary.max_heap import MaxHeap, MaxArrayBasedHeap
3+
4+
5+
__all__ = [
6+
"MinHeap",
7+
"MaxHeap",
8+
"MaxArrayBasedHeap",
9+
"MinArrayBasedHeap"
10+
]
Lines changed: 6 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,7 @@
1-
from heapq import heapify, heappop
2-
from typing import Any, List, Union
1+
from datastructures.trees.heaps.binary.max_heap.max_array_heap import MaxArrayBasedHeap
2+
from datastructures.trees.heaps.binary.max_heap.max_heap import MaxHeap
33

4-
from datastructures.trees.heaps import Heap
5-
from datastructures.trees.heaps.node import HeapNode
6-
7-
8-
class MaxHeap(Heap):
9-
def __init__(self, heap: List[HeapNode] = None):
10-
super().__init__()
11-
self.heap_dict = {}
12-
self.idx_of_element = {}
13-
if heap is None:
14-
heap = []
15-
self.heap = self.__build_heap(heap)
16-
heapify(self.heap)
17-
18-
def __len__(self):
19-
return len(self.heap)
20-
21-
def __find_smaller_child(self, index: int) -> int:
22-
left_child_index = self.get_left_child_index(index)
23-
right_child_index = self.get_right_child_index(index)
24-
25-
# no right child
26-
if right_child_index > len(self.heap):
27-
# not left child
28-
if left_child_index >= len(self.heap):
29-
return -1
30-
# left child only
31-
else:
32-
return left_child_index
33-
else:
34-
# compare left & right children
35-
if self.heap[left_child_index] < self.heap[right_child_index]:
36-
return left_child_index
37-
else:
38-
return right_child_index
39-
40-
def __bubble_down(self, idx: int):
41-
min_child_index = self.__find_smaller_child(idx)
42-
43-
if min_child_index == -1:
44-
return
45-
46-
if self.heap[idx] > self.heap[min_child_index]:
47-
self.heap[idx], self.heap[min_child_index] = (
48-
self.heap[min_child_index],
49-
self.heap[idx],
50-
)
51-
(
52-
self.idx_of_element[self.heap[min_child_index]],
53-
self.idx_of_element[self.heap[idx]],
54-
) = (
55-
self.idx_of_element[self.idx_of_element[self.heap[idx]]],
56-
self.idx_of_element[self.idx_of_element[self.heap[min_child_index]]],
57-
)
58-
59-
self.__bubble_down(min_child_index)
60-
61-
def __bubble_up(self, idx: int):
62-
if idx == 0:
63-
return
64-
parent_idx = (idx - 1) // 2
65-
if self.heap[idx] < self.heap[parent_idx]:
66-
# swap indices & recurse
67-
self.heap[idx], self.heap[parent_idx] = (
68-
self.heap[parent_idx],
69-
self.heap[idx],
70-
)
71-
(
72-
self.idx_of_element[self.heap[parent_idx]],
73-
self.idx_of_element[self.heap[idx]],
74-
) = (
75-
self.idx_of_element[self.idx_of_element[self.heap[idx]]],
76-
self.idx_of_element[self.idx_of_element[self.heap[parent_idx]]],
77-
)
78-
79-
self.__bubble_up(parent_idx)
80-
81-
def __build_heap(self, array: List[HeapNode]) -> List[HeapNode]:
82-
last_idx = len(array) - 1
83-
start_from = self.get_parent_index(last_idx)
84-
85-
for idx, node in enumerate(array):
86-
self.idx_of_element[node] = idx
87-
self.heap_dict[node.name] = node.data
88-
89-
for i in range(start_from, -1, -1):
90-
self.__bubble_down(i)
91-
92-
return array
93-
94-
def insert_data(self, data: Any):
95-
"""
96-
Inserts a value into the heap
97-
"""
98-
if data is None:
99-
raise TypeError("Data item can not be None")
100-
node = HeapNode(data)
101-
self.heap.append(node)
102-
self.__bubble_up(len(self.heap) - 1)
103-
104-
def decrease_value_at(self, index, new_val):
105-
"""
106-
Decrease value of key at index 'index' to new_val
107-
It is assumed that new_val is smaller than heap[i]
108-
"""
109-
self.heap[index] = new_val
110-
while index != 0 and self.heap[self.get_parent_index(index)] > self.heap[index]:
111-
# Swap heap[i] with heap[parent(i)]
112-
self.heap[index], self.heap[self.get_parent_index(index)] = (
113-
self.heap[self.get_parent_index(index)],
114-
self.heap[index],
115-
)
116-
117-
def delete(self) -> Any:
118-
return self.remove_min()
119-
120-
def remove_min(self) -> Any:
121-
"""
122-
Removes and returns the smallest value in the Heap
123-
"""
124-
return heappop(self.heap)
125-
126-
def delete_key(self, index):
127-
"""
128-
Deletes key at index "index". It first reduces value to minus infinite and then calls remove_min
129-
"""
130-
self.decrease_value_at(index, float("-inf"))
131-
self.remove_min()
132-
133-
def get_minimum(self):
134-
"""
135-
Returns the minimum value in the heap without removing it
136-
"""
137-
return self.heap[0]
138-
139-
def is_empty(self) -> bool:
140-
"""
141-
Checks if the heap is empty
142-
"""
143-
return len(self.heap) == 0
144-
145-
def peek(self) -> Union[HeapNode, None]:
146-
"""
147-
Gets the smallest item in the heap
148-
"""
149-
return self.heap[0] if self.heap else None
150-
151-
def size(self):
152-
"""
153-
Returns the size of the heap
154-
"""
155-
return len(self.heap)
4+
__all__ = [
5+
"MaxArrayBasedHeap",
6+
"MaxHeap"
7+
]

datastructures/trees/heaps/binary/max_heap/max_array_heap.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any
22

3-
from datastructures.trees.heaps import ArrayBasedHeap
3+
from datastructures.trees.heaps.array_heap import ArrayBasedHeap
44

55

66
class MaxArrayBasedHeap(ArrayBasedHeap):
@@ -11,7 +11,7 @@ class MaxArrayBasedHeap(ArrayBasedHeap):
1111
def __init__(self):
1212
super().__init__()
1313

14-
def insert_data(self, value: Any):
14+
def insert(self, value: Any):
1515
"""
1616
Inserts a value into the heap
1717
"""

0 commit comments

Comments
 (0)