Skip to content

Commit 6317213

Browse files
committed
add heap in python
1 parent 7e31e6e commit 6317213

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

Heaps/heap.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
'''
2+
Implement a Min-Heap class that supports
3+
4+
Building a Min Heap from an input array of integers.
5+
Inserting integers in the heap.
6+
Removing the heap's minimum / root value.
7+
Peeking at the heap's minimum / root value.
8+
Sifting integers up and down the heap, which is to be used when inserting and removing values.
9+
10+
Note that the heap should be represented in the form of an array.
11+
12+
Explanation:
13+
14+
The code snippet implements a MinHeap data structure in Go.
15+
16+
- `NewMinHeap`: This function creates a new MinHeap from an input array and returns a pointer to the MinHeap object.
17+
It calls the `BuildHeap` method to construct the heap structure.
18+
- `BuildHeap`: This method constructs the heap by iteratively calling `siftDown` on each parent node starting from the
19+
last non-leaf node.
20+
- `siftDown`: This method corrects the heap property by moving an element down the heap until it reaches its correct position. It compares the element with its children and swaps it with the smaller child if necessary.
21+
- `siftUp`: This method corrects the heap property by moving an element up the heap until it reaches its correct position.
22+
It compares the element with its parent and swaps it if necessary.
23+
- `Peek`: This method returns the minimum element in the heap (the root of the heap) without removing it.
24+
- `Remove`: This method removes and returns the minimum element in the heap. It swaps the root with the last element,
25+
removes the last element from the heap, and then calls `siftDown` to maintain the heap property.
26+
- `Insert`: This method inserts a new element into the heap. It appends the element to the end of the heap and then
27+
calls `siftUp` to maintain the heap property.
28+
- `swap`: This method swaps two elements in the heap given their indices.
29+
- `length`: This method returns the number of elements in the heap.
30+
31+
Overall, this code provides a basic implementation of a MinHeap data structure, allowing for efficient insertion, removal,
32+
and retrieval of the minimum element.
33+
34+
BuildHeap: O(n) time | O(1) space - where n is the length of the input array
35+
SiftDown: O(log(n)) time | O(1) space - where n is the length of the heap
36+
SiftUp: O(log(n)) time | O(1) space - where n is the length of the heap
37+
Peek: O(1) time | O(1) space
38+
Remove: O(log(n)) time | O(1) space - where n is the length of the heap
39+
Insert: O(log(n)) time | O(1) space - where n is the length of the heap
40+
41+
'''
42+
class MinHeap:
43+
def __init__(self):
44+
self.heap = [] # The heap represented as a list
45+
46+
def build_heap(self, array):
47+
# Build the heap by calling sift_down on each parent node
48+
first = (len(array) - 2) // 2 # Start from the last parent node
49+
for current_idx in range(first, -1, -1):
50+
self.sift_down(current_idx, len(array) - 1)
51+
52+
def sift_down(self, current_idx, end_idx):
53+
child_one_idx = current_idx * 2 + 1 # Calculate the index of the first child
54+
while child_one_idx <= end_idx:
55+
child_two_idx = -1 # Initialize the index of the second child
56+
if current_idx * 2 + 2 <= end_idx:
57+
child_two_idx = current_idx * 2 + 2 # Calculate the index of the second child if it exists
58+
index_to_swap = child_one_idx # Assume the first child is the one to swap with
59+
if child_two_idx > -1 and self.heap[child_one_idx] > self.heap[child_two_idx]:
60+
# If the second child exists and is smaller, update the index to swap with
61+
index_to_swap = child_two_idx
62+
if self.heap[current_idx] > self.heap[index_to_swap]:
63+
# If the current element is greater than the one to swap with, perform the swap
64+
self.swap(current_idx, index_to_swap)
65+
current_idx = index_to_swap
66+
child_one_idx = current_idx * 2 + 1 # Update the index of the first child
67+
else:
68+
return
69+
70+
def sift_up(self):
71+
current_idx = len(self.heap) - 1 # Start from the last element
72+
parent_idx = (current_idx - 1) // 2 # Calculate the index of the parent
73+
while current_idx > 0:
74+
current, parent = self.heap[current_idx], self.heap[parent_idx]
75+
if current < parent:
76+
# If the current element is smaller than the parent, perform the swap
77+
self.swap(current_idx, parent_idx)
78+
current_idx = parent_idx
79+
parent_idx = (current_idx - 1) // 2 # Update the index of the parent
80+
else:
81+
return
82+
83+
def peek(self):
84+
if not self.heap:
85+
return -1
86+
return self.heap[0] # Return the minimum element at the top of the heap
87+
88+
def remove(self):
89+
l = len(self.heap)
90+
self.swap(0, l - 1) # Swap the root with the last element
91+
peeked = self.heap.pop() # Remove the last element (minimum) and store it
92+
self.sift_down(0, l - 2) # Sift down the new root element
93+
return peeked
94+
95+
def insert(self, value):
96+
self.heap.append(value) # Append the new element to the end of the heap
97+
self.sift_up() # Sift up the new element to its correct position
98+
99+
def swap(self, i, j):
100+
self.heap[i], self.heap[j] = self.heap[j], self.heap[i] # Swap elements at indices i and j
101+
102+
def length(self):
103+
return len(self.heap) # Return the number of elements in the heap
104+
105+
106+
def new_min_heap(array):
107+
heap = MinHeap() # Create a new MinHeap object
108+
heap.build_heap(array) # Build the heap using the given array
109+
return heap

0 commit comments

Comments
 (0)