Skip to content

Commit 9afb712

Browse files
committed
Reverted back last commit due to inconsistent code
1 parent 937743f commit 9afb712

File tree

2 files changed

+135
-1
lines changed

2 files changed

+135
-1
lines changed

pygorithm/data_structures/heap.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Author: ALLSTON MICKEY
2+
# Contributed: OMKAR PATHAK
3+
# Created On: 11th August 2017
4+
5+
from queue import Queue
6+
7+
# min-heap implementation as priority queue
8+
class Heap(Queue):
9+
def parent_idx(self, idx):
10+
return idx / 2
11+
12+
def left_child_idx(self, idx):
13+
return (idx * 2) + 1
14+
15+
def right_child_idx(self, idx):
16+
return (idx * 2) + 2
17+
18+
def insert(self, data):
19+
super(Heap, self).enqueue(data)
20+
if self.rear >= 1: # heap may need to be fixed
21+
self.heapify_up()
22+
23+
def heapify_up(self):
24+
'''
25+
Start at the end of the tree (first enqueued item).
26+
27+
Compare the rear item to its parent, swap if
28+
the parent is larger than the child (min-heap property).
29+
Repeat until the min-heap property is met.
30+
'''
31+
child = self.rear
32+
parent = self.parent_idx(child)
33+
while self.queue[child] < self.queue[self.parent_idx(child)]:
34+
# Swap (sift up) and update child:parent relation
35+
self.queue[child], self.queue[parent] = self.queue[parent], self.queue[child]
36+
child = parent
37+
parent = self.parent_idx(child)
38+
39+
def pop(self):
40+
''' Removes the lowest value element (highest priority) from the heap '''
41+
min = self.dequeue()
42+
if self.rear >= 1: # heap may need to be fixed
43+
self.heapify_down()
44+
return min
45+
46+
def favorite(self, parent):
47+
''' Determines which child has the highest priority by 3 cases '''
48+
left = self.left_child_idx(parent)
49+
right = self.right_child_idx(parent)
50+
51+
if left <= self.rear and right <= self.rear: # case 1: both nodes exist
52+
if self.queue[left] <= self.queue[right]:
53+
return left
54+
else:
55+
return right
56+
elif left <= self.rear: # case 2: only left exists
57+
return left
58+
else: # case 3: no children (if left doesn't exist, neither can the right)
59+
return None
60+
61+
def heapify_down(self):
62+
'''
63+
Select the root and sift down until min-heap property is met.
64+
65+
While a favorite child exists, and that child is smaller
66+
than the parent, swap them (sift down).
67+
'''
68+
cur = ROOT = 0 # start at the root
69+
fav = self.favorite(cur) # determine favorite child
70+
while self.queue[fav] is not None:
71+
if self.queue[cur] > self.queue[fav]:
72+
# Swap (sift down) and update parent:favorite relation
73+
fav = self.favorite(cur)
74+
self.queue[cur], self.queue[fav] = self.queue[fav], self.queue[cur]
75+
cur = fav
76+
else:
77+
return
78+
79+
def get_code(self):
80+
''' returns the code for the current class '''
81+
import inspect
82+
return inspect.getsource(Heap)

tests/test_data_structure.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@
44
stack,
55
queue,
66
linked_list,
7+
<<<<<<< Updated upstream
78
tree)
9+
=======
10+
tree,
11+
heap,
12+
graph)
13+
>>>>>>> Stashed changes
814

915
class TestStack(unittest.TestCase):
1016
def test_stack(self):
@@ -59,7 +65,7 @@ def test_deque(self):
5965

6066
self.assertEqual(myDeque.delete_rear(), 10)
6167
self.assertEqual(myDeque.delete_front(), 3)
62-
68+
6369
class TestLinkedList(unittest.TestCase):
6470
def test_singly_linked_list(self):
6571
List = linked_list.SinglyLinkedList()
@@ -131,5 +137,51 @@ def test_binary_search_tree(self):
131137

132138
self.assertTrue(root.find(8))
133139

140+
<<<<<<< Updated upstream
141+
=======
142+
class TestHeap(unittest.TestCase):
143+
def test_heap(self):
144+
myHeap = heap.Heap(limit = 4)
145+
myHeap.insert(2) # [2]
146+
myHeap.insert(10) # [2, 10]
147+
myHeap.insert(12) # [2, 10, 12]
148+
myHeap.insert(3) # [2, 3, 10, 12]
149+
150+
expectedResult = [2, 3, 10, 12]
151+
self.assertEqual(myHeap.queue(), expectedResult)
152+
153+
self.assertEqual(myHeap.pop(), 2)
154+
expectedResult = [3, 10, 12]
155+
self.assertEqual(myHeap.queue(), expectedResult)
156+
157+
self.assertEqual(myHeap.pop(), 3)
158+
expectedResult = [10, 12]
159+
self.assertEqual(myHeap.queue(), expectedResult)
160+
161+
self.assertEqual(myHeap.pop(), 10)
162+
expectedResult = [12]
163+
self.assertEqual(myHeap.queue(), expectedResult)
164+
165+
self.assertEqual(myHeap.pop(), 12)
166+
expectedResult = []
167+
self.assertEqual(myHeap.queue(), expectedResult)
168+
169+
self.assertTrue(myHeap.is_empty())
170+
171+
class TestGraph(unittest.TestCase):
172+
def test_topological_sort(self):
173+
myGraph = graph.TopologicalSort()
174+
myGraph.add_edge(5, 2)
175+
myGraph.add_edge(5, 0)
176+
myGraph.add_edge(4, 0)
177+
myGraph.add_edge(4, 1)
178+
myGraph.add_edge(2, 3)
179+
myGraph.add_edge(3, 1)
180+
181+
ans = myGraph.topological_sort()
182+
expectedResult = [5, 4, 2, 3, 1, 0]
183+
self.assertEqual(ans, expectedResult)
184+
185+
>>>>>>> Stashed changes
134186
if __name__ == '__main__':
135187
unittest.main()

0 commit comments

Comments
 (0)