Skip to content

Commit fc4c0f5

Browse files
lanzhiwangcclauss
authored andcommitted
implement max heap and more pythonic (TheAlgorithms#1685)
* implement max heap and more pythonic * add doctests for heap
1 parent d09a805 commit fc4c0f5

File tree

1 file changed

+115
-67
lines changed

1 file changed

+115
-67
lines changed

data_structures/heap/heap.py

+115-67
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,134 @@
1-
#!/usr/bin/python
1+
#!/usr/bin/python3
22

3-
# This heap class start from here.
4-
class Heap:
5-
def __init__(self): # Default constructor of heap class.
3+
4+
class Heap(object):
5+
"""
6+
>>> unsorted = [103, 9, 1, 7, 11, 15, 25, 201, 209, 107, 5]
7+
>>> h = Heap()
8+
>>> h.build_heap(unsorted)
9+
>>> h.display()
10+
[209, 201, 25, 103, 107, 15, 1, 9, 7, 11, 5]
11+
>>>
12+
>>> h.get_max()
13+
209
14+
>>> h.display()
15+
[201, 107, 25, 103, 11, 15, 1, 9, 7, 5]
16+
>>>
17+
>>> h.insert(100)
18+
>>> h.display()
19+
[201, 107, 25, 103, 100, 15, 1, 9, 7, 5, 11]
20+
>>>
21+
>>> h.heap_sort()
22+
>>> h.display()
23+
[1, 5, 7, 9, 11, 15, 25, 100, 103, 107, 201]
24+
>>>
25+
"""
26+
def __init__(self):
627
self.h = []
7-
self.currsize = 0
28+
self.curr_size = 0
829

9-
def leftChild(self, i):
10-
if 2 * i + 1 < self.currsize:
11-
return 2 * i + 1
30+
def get_left_child_index(self, i):
31+
left_child_index = 2 * i + 1
32+
if left_child_index < self.curr_size:
33+
return left_child_index
1234
return None
1335

14-
def rightChild(self, i):
15-
if 2 * i + 2 < self.currsize:
16-
return 2 * i + 2
36+
def get_right_child(self, i):
37+
right_child_index = 2 * i + 2
38+
if right_child_index < self.curr_size:
39+
return right_child_index
1740
return None
1841

19-
def maxHeapify(self, node):
20-
if node < self.currsize:
21-
m = node
22-
lc = self.leftChild(node)
23-
rc = self.rightChild(node)
24-
if lc is not None and self.h[lc] > self.h[m]:
25-
m = lc
26-
if rc is not None and self.h[rc] > self.h[m]:
27-
m = rc
28-
if m != node:
29-
temp = self.h[node]
30-
self.h[node] = self.h[m]
31-
self.h[m] = temp
32-
self.maxHeapify(m)
33-
34-
def buildHeap(
35-
self, a
36-
): # This function is used to build the heap from the data container 'a'.
37-
self.currsize = len(a)
38-
self.h = list(a)
39-
for i in range(self.currsize // 2, -1, -1):
40-
self.maxHeapify(i)
41-
42-
def getMax(self): # This function is used to get maximum value from the heap.
43-
if self.currsize >= 1:
42+
def max_heapify(self, index):
43+
if index < self.curr_size:
44+
largest = index
45+
lc = self.get_left_child_index(index)
46+
rc = self.get_right_child(index)
47+
if lc is not None and self.h[lc] > self.h[largest]:
48+
largest = lc
49+
if rc is not None and self.h[rc] > self.h[largest]:
50+
largest = rc
51+
if largest != index:
52+
self.h[largest], self.h[index] = self.h[index], self.h[largest]
53+
self.max_heapify(largest)
54+
55+
def build_heap(self, collection):
56+
self.curr_size = len(collection)
57+
self.h = list(collection)
58+
if self.curr_size <= 1:
59+
return
60+
for i in range(self.curr_size // 2 - 1, -1, -1):
61+
self.max_heapify(i)
62+
63+
def get_max(self):
64+
if self.curr_size >= 2:
4465
me = self.h[0]
45-
temp = self.h[0]
46-
self.h[0] = self.h[self.currsize - 1]
47-
self.h[self.currsize - 1] = temp
48-
self.currsize -= 1
49-
self.maxHeapify(0)
66+
self.h[0] = self.h.pop(-1)
67+
self.curr_size -= 1
68+
self.max_heapify(0)
5069
return me
70+
elif self.curr_size == 1:
71+
self.curr_size -= 1
72+
return self.h.pop(-1)
5173
return None
5274

53-
def heapSort(self): # This function is used to sort the heap.
54-
size = self.currsize
55-
while self.currsize - 1 >= 0:
56-
temp = self.h[0]
57-
self.h[0] = self.h[self.currsize - 1]
58-
self.h[self.currsize - 1] = temp
59-
self.currsize -= 1
60-
self.maxHeapify(0)
61-
self.currsize = size
62-
63-
def insert(self, data): # This function is used to insert data in the heap.
75+
def heap_sort(self):
76+
size = self.curr_size
77+
for j in range(size - 1, 0, -1):
78+
self.h[0], self.h[j] = self.h[j], self.h[0]
79+
self.curr_size -= 1
80+
self.max_heapify(0)
81+
self.curr_size = size
82+
83+
def insert(self, data):
6484
self.h.append(data)
65-
curr = self.currsize
66-
self.currsize += 1
67-
while self.h[curr] > self.h[curr / 2]:
68-
temp = self.h[curr / 2]
69-
self.h[curr / 2] = self.h[curr]
70-
self.h[curr] = temp
71-
curr = curr / 2
72-
73-
def display(self): # This function is used to print the heap.
85+
curr = (self.curr_size - 1) // 2
86+
self.curr_size += 1
87+
while curr >= 0:
88+
self.max_heapify(curr)
89+
curr = (curr - 1) // 2
90+
91+
def display(self):
7492
print(self.h)
7593

7694

7795
def main():
78-
l = list(map(int, input().split()))
79-
h = Heap()
80-
h.buildHeap(l)
81-
h.heapSort()
82-
h.display()
96+
for unsorted in [
97+
[],
98+
[0],
99+
[2],
100+
[3, 5],
101+
[5, 3],
102+
[5, 5],
103+
[0, 0, 0, 0],
104+
[1, 1, 1, 1],
105+
[2, 2, 3, 5],
106+
[0, 2, 2, 3, 5],
107+
[2, 5, 3, 0, 2, 3, 0, 3],
108+
[6, 1, 2, 7, 9, 3, 4, 5, 10, 8],
109+
[103, 9, 1, 7, 11, 15, 25, 201, 209, 107, 5],
110+
[-45, -2, -5]
111+
]:
112+
print('source unsorted list: %s' % unsorted)
113+
114+
h = Heap()
115+
h.build_heap(unsorted)
116+
print('after build heap: ', end=' ')
117+
h.display()
118+
119+
print('max value: %s' % h.get_max())
120+
print('delete max value: ', end=' ')
121+
h.display()
122+
123+
h.insert(100)
124+
print('after insert new value 100: ', end=' ')
125+
h.display()
126+
127+
h.heap_sort()
128+
print('heap sort: ', end=' ')
129+
h.display()
130+
print()
83131

84132

85-
if __name__ == "__main__":
133+
if __name__ == '__main__':
86134
main()

0 commit comments

Comments
 (0)