Skip to content

Commit 6b004a5

Browse files
author
Albert Hu
authored
Merge pull request #27 from alberthu16/day38
Day 38: implement a heap pt 1
2 parents 03a3190 + 06bcbc7 commit 6b004a5

File tree

2 files changed

+227
-0
lines changed

2 files changed

+227
-0
lines changed

day38/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
Today I'm going to implement a min heap.
2+
3+
What is a heap?
4+
5+
From http://www.cprogramming.com/tutorial/computersciencetheory/heap.html:
6+
7+
"A heap is a partially sorted binary tree. Although a heap is not completely
8+
in order, it conforms to a sorting principle: every node has a value less
9+
(for the sake of simplicity, we will assume that all orderings are from
10+
least to greatest) than either of its children. Additionally, a heap is
11+
a "complete tree" -- a complete tree is one in which there are no gaps
12+
between leaves. For instance, a tree with a root node that has only one
13+
child must have its child as the left node. More precisely, a complete tree
14+
is one that has every level filled in before adding a node to the next level,
15+
and one that has the nodes in a given level filled in from left to right,
16+
with no breaks."
17+
18+
Basically, a one-node min heap might look something like this:
19+
20+
```
21+
7
22+
```
23+
24+
And a two-node min heap might look something like this:
25+
26+
```
27+
7
28+
/
29+
9
30+
```
31+
32+
three nodes:
33+
34+
```
35+
7
36+
/ \
37+
9 8
38+
```
39+
40+
four nodes:
41+
42+
```
43+
7
44+
/ \
45+
10 18
46+
/
47+
19
48+
```
49+
50+
and so on.
51+
52+
Here are some specs for my basic min heap that contains `n` integers:
53+
54+
getMin - takes no arguments, extracts and returns the minimum value in the heap.
55+
The rest of the heap is reorganized so that the min value is still at
56+
the top. Finishes in `O(n)` time.
57+
58+
peek - takes no arguments, returns the minimum value in the heap. Should return
59+
in `O(1)` time.
60+
61+
push - takes an integer as an argument and adds it into the heap, returning
62+
nothing. Should complete in `O(logn)` time.
63+
64+
heapify - takes an array of integers and forms a heap out of them. Should run in
65+
`O(nlogn)` (?) time.
66+
67+
size - takes no arguments and returns the number of integers in the heap `n`
68+
in `O(1)` time.
69+
70+
isEmpty - takes no arguments and returns `True` if there are no elements in the
71+
heap, and `False` if there ARE elements in the heap in `O(1)` time.
72+
73+
## Code
74+
75+
[Python](./heap.py)
76+
77+
## Follow-up
78+
79+
Why use a heap?
80+
81+
If some kind of ordering is required, i.e. max or min ordering, a heap is an
82+
efficient way to maintain that ordering even when elements are being deleted
83+
and added. The tree structure of the heap allows you to find elements in
84+
`O(logn)` time rather than `O(n)` time like in a normal array or linked list.

day38/heap.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
class MinHeap:
2+
def __init__(self, arr=[]):
3+
if len(arr) > 0:
4+
self.heap = self.heapify(arr)
5+
else:
6+
self.heap = []
7+
8+
self.size = 0
9+
10+
def getMin(self):
11+
if self.size > 0
12+
ret = self.heap[0] #[1]
13+
self.heap[0] = self.heap[-1] #[1]
14+
self.heap.pop() #[]
15+
self.size -= 1
16+
self.bubbleDown() #[]
17+
return ret
18+
19+
def peek(self):
20+
if self.size > 0
21+
return self.heap[0]
22+
23+
def push(self, val):
24+
self.heap.append(val)
25+
self.bubbleUp()
26+
self.size += 1
27+
28+
def heapify(self, arr):
29+
# TODO
30+
return
31+
32+
def size(self):
33+
return self.size
34+
35+
def isEmpty(self):
36+
return self.size == 0
37+
38+
def bubbleDown(self):
39+
# TODO
40+
return
41+
42+
def bubbleUp(self):
43+
# TODO
44+
return
45+
46+
def testPush():
47+
h = MinHeap()
48+
h.push(2)
49+
assert h.heap[0] == 2
50+
51+
h.push(3)
52+
assert h.heap[0] == 2
53+
54+
h.push(1)
55+
assert h.heap[0] == 1
56+
57+
h.push(5)
58+
assert h.heap[0] == 1
59+
60+
h.push(-1)
61+
assert h.heap[0] == -1
62+
63+
def testHeapify():
64+
# heap1 = MinHeap([1, 2, 3, 4, 5])
65+
# heap2 = MinHeap([])
66+
# heap3 = MinHeap([5, 4, 3, 2, 1])
67+
# heap4 = MinHeap([3, 1])
68+
# heap5 = MinHeap([0, -1, 1, -2, 2])
69+
# assert isMinHeap(heap1)
70+
# assert isMinHeap(heap2)
71+
# assert isMinHeap(heap3)
72+
# assert isMinHeap(heap4)
73+
# assert isMinHeap(heap5)
74+
assert True
75+
76+
def testGetMin():
77+
heap = MinHeap([2, 5, 20])
78+
assert heap.getMin() == 2
79+
assert heap.getMin() == 5
80+
81+
heap1 = MinHeap([1, 2, 3, 4, 5])
82+
assert heap1.getMin() == 1
83+
assert heap1.getMin() == 2
84+
85+
heap2 = MinHeap([5, 4, 3, 2, 1])
86+
assert heap2.getMin() == 1
87+
assert heap2.getMin() == 2
88+
89+
heap3 = MinHeap([2, 5, 3, 7, -1])
90+
assert heap3.getMin() == -1
91+
assert heap3.getMin() == 2
92+
93+
def testPeek():
94+
heap = MinHeap([2, 5, 20])
95+
assert heap.peek() == 2
96+
assert heap.peek() == 2
97+
98+
heap1 = MinHeap([1, 2, 3, 4, 5])
99+
assert heap1.peek() == 1
100+
assert heap1.peek() == 1
101+
102+
heap2 = MinHeap([5, 4, 3, 2, 1])
103+
assert heap2.peek() == 1
104+
assert heap2.peek() == 1
105+
106+
heap3 = MinHeap([2, 5, 3, 7, -1])
107+
assert heap3.peek() == -1
108+
assert heap3.peek() == -1
109+
110+
def testSize():
111+
heap = MinHeap()
112+
assert heap.size() == 0
113+
114+
heap2 = MinHeap([1])
115+
assert heap.size() == 1
116+
117+
heap3 = MinHeap([1, 2, 3, 4])
118+
assert heap.size() == 4
119+
120+
def testIsEmpty():
121+
heap = MinHeap()
122+
assert heap.isEmpty()
123+
124+
heap2 = MinHeap([1])
125+
assert not heap.isEmpty()
126+
127+
heap3 = MinHeap([1, 2, 3])
128+
assert not heap.isEmpty()
129+
130+
def testEverything():
131+
assert True
132+
133+
def tests():
134+
testPush()
135+
testHeapify()
136+
testGetMin()
137+
testPeek()
138+
testSize()
139+
testIsEmpty()
140+
testEverything()
141+
142+
if __name__ == "__main__":
143+
tests()

0 commit comments

Comments
 (0)