Skip to content

Commit b821e06

Browse files
committed
Heap Sort
1 parent 09940c0 commit b821e06

File tree

9 files changed

+182
-10
lines changed

9 files changed

+182
-10
lines changed

DOC/Heap_Sort.md

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Heap Sort
2+
3+
Heaps can be used in sorting an array. In max-heaps, the maximum element will always be at the root. Heap Sort uses this property of heap to sort the array.
4+
5+
Consider an array `arr[]` which is to be sorted using Heap Sort.
6+
7+
- Initially build a max heap of elements in `arr[]`.
8+
- The root element, `arr[1]`, will contain the maximum element of `arr[]`. After that, swap this element with the last element of `arr[]` and heapify the max heap excluding the last element which is already in its correct position and then decrease the length of the heap by one.
9+
- Repeat step 2, until all the elements are in their correct position.
10+
11+
## Implementation
12+
13+
To heapify subtree rooted at index, i. n is the size of the heap.
14+
15+
```python
16+
def heapify(data, n, i, draw_data, time_tick):
17+
```
18+
19+
Initialize largest as root.
20+
21+
```python
22+
largest = i
23+
left = 2*i + 1
24+
right = 2*i + 2
25+
```
26+
27+
See if the left child of root exists and is greater than the root.
28+
29+
```python
30+
if left < n and data[i] < data[left]:
31+
largest = left
32+
```
33+
34+
See if the right child of root exists and is greater than the root.
35+
36+
```python
37+
if right < n and data[largest] < data[right]:
38+
largest = right
39+
```
40+
41+
Change root, if needed
42+
43+
```python
44+
if largest != i:
45+
data[i], data[largest] = data[largest], data[i]
46+
```
47+
48+
Heapify the root.
49+
50+
```python
51+
heapify(data, n, largest, draw_data, time_tick)
52+
```
53+
54+
The main function to sort an array of a given size.
55+
56+
```python
57+
def heap_sort(data, draw_data, time_tick):
58+
n = len(data)
59+
```
60+
61+
Build a maxheap. Since the last parent will be at ((n//2)-1) we can start at that location.
62+
63+
```python
64+
for i in range(n-1, -1, -1):
65+
heapify(data, n, i, draw_data, time_tick)
66+
```
67+
68+
One by one extract elements.
69+
70+
```python
71+
for i in range(n-1, 0, -1):
72+
data[i], data[0] = data[0], data[i]
73+
heapify(data, i, 0, draw_data, time_tick)
74+
```
75+
76+
Draw the data being compared and finalized.
77+
78+
```python
79+
draw_data(data, [YELLOW if x == i else BLUE for x in range(n)])
80+
time.sleep(time_tick)
81+
draw_data(data, [BLUE for x in range(len(data))])
82+
```
83+
84+
## Example
85+
86+
In the diagram below, initially, there is an unsorted array `arr[]` having 6 elements and then max-heap will be built.
87+
88+
<p align="center">
89+
<img src="../images/heap_sort_1.png">
90+
</p>
91+
92+
After building max-heap, the elements in the array `arr[]` will be:
93+
94+
<p align="center">
95+
<img src="../images/heap_sort_2.png">
96+
</p>
97+
98+
- *Step 1:* 8 is swapped with 5.
99+
- *Step 2:* 8 is disconnected from the heap as 8 is the incorrect position now and.
100+
- *Step 3:* Max-heap is created and 7 is swapped with 3.
101+
- *Step 4:* 7 is disconnected from the heap.
102+
- *Step 5:* Max heap is created and 5 is swapped with 1.
103+
- *Step 6:* 5 is disconnected from the heap.
104+
- *Step 7:* Max heap is created and 4 is swapped with 3.
105+
- *Step 8:* 4 is disconnected from the heap.
106+
- *Step 9:* Max heap is created and 3 is swapped with 1.
107+
- *Step 10:* 3 is disconnected.
108+
109+
<p align="center">
110+
<img src="../images/heap_sort_3.png">
111+
</p>
112+
113+
After all the steps, we will get a sorted array.
114+
115+
<p align="center">
116+
<img src="../images/heap_sort_4.png">
117+
</p>

README.md

+25-9
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ In this project, we will a Sorting Algorithm Visualizar using Python and Tkinter
1010
<img src="images/file_structure.png"/>
1111
</p>
1212

13-
`main.py` will be our main Python file which we will execute. `colors.py` will contain some hexadecimal values of colors that we'll need. The file `__init__.py`, will allow the algorithms folder to act as a Python package.
13+
`main.py` will be our main Python file which we will execute. `colors.py` will contain some hexadecimal values of colors that we'll need. The file `__init__.py`, will allow the algorithms folder to act as a Python package.
1414

1515
## colors.py
1616

17-
In this file, we will store some hexadecimal values of colors as variables.
17+
In this file, we will store some hexadecimal values of colors as variables.
1818

1919
```python
2020
DARK_GRAY = '#65696B'
@@ -32,7 +32,7 @@ PURPLE = '#BF01FB'
3232

3333
## main.py
3434

35-
This file will be our main executable file.
35+
This file will be our main executable file.
3636

3737
### Interface
3838

@@ -56,14 +56,15 @@ root.mainloop()
5656
### Variables and Empty Functions
5757

5858
We will need random to create an array
59+
5960
```python
6061
import random
6162
```
6263

6364
Now, we will add some variables and functions. We will edit the functions one by one. For now, we will just `pass`.
6465

65-
6666
*algo_list* is to select which algorithm we want to use to sort
67+
6768
```python
6869
algorithm_name = StringVar()
6970
algorithm_list = [
@@ -73,40 +74,47 @@ algorithm_list = [
7374
'Insertion Sort',
7475
'Quick Sort',
7576
'Counting Sort',
76-
'Radix Sort'
77+
'Radix Sort',
78+
'Heap Sort'
7779
]
7880
```
7981

8082
*speed_list* is for selecting sorting speed
83+
8184
```python
8285
speed_name = StringVar()
8386
speed_list = ['Fast', 'Medium', 'Slow']
8487
```
8588

86-
This empty list will be filled with random values every time we generate a new array
89+
This empty list will be filled with random values every time we generate a new array.
90+
8791
```python
8892
data = []
8993
```
9094

91-
This function will draw randomly generated list data[] on the canvas as vertical bars
95+
This function will draw randomly generated list data[] on the canvas as vertical bars.
96+
9297
```python
9398
def draw_data(data, colorArray):
9499
pass
95100
```
96101

97102
This function will generate an array with random values every time we hit the generate button.
103+
98104
```python
99105
def generate():
100106
pass
101107
```
102108

103109
This function will set the sorting speed
110+
104111
```python
105112
def set_speed():
106113
pass
107114
```
108115

109116
This function will trigger a selected algorithm and start sorting
117+
110118
```python
111119
def sort():
112120
pass
@@ -130,6 +138,7 @@ UI_frame.grid(row=0, column=0, padx=10, pady=5)
130138
```
131139

132140
Dropdown to select sorting algorithm
141+
133142
```python
134143
l1 = Label(UI_frame, text='Algorithm: ', bg=WHITE)
135144
l1.grid(row=0, column=0, padx=10, pady=5, sticky=W)
@@ -139,6 +148,7 @@ algorithm_menu.current(0)
139148
```
140149

141150
Dropdown to select sorting speed
151+
142152
```python
143153
l2 = Label(UI_frame, text='Sorting Speed: ', bg=WHITE)
144154
l2.grid(row=1, column=0, padx=10, pady=5, sticky=W)
@@ -148,18 +158,21 @@ speed_menu.current(0)
148158
```
149159

150160
Button for generating array
161+
151162
```python
152163
b1 = Button(UI_frame, text='Generate Array', command=generate, bg=LIGHT_GRAY, width=20)
153164
b1.grid(row=2, column=0, padx=5, pady=5)
154165
```
155166

156167
Sort button
168+
157169
```python
158170
b2 = Button(UI_frame, text='Sort', command=sort, bg=LIGHT_GRAY, width=20)
159171
b2.grid(row=2, column= 1, padx=5, pady=5)
160172
```
161173

162174
Canvas to draw our array
175+
163176
```python
164177
canvas = Canvas(root, width=800, height=400, bg=WHITE)
165178
canvas.grid(row=1, column=0, padx=10, pady=5)
@@ -171,7 +184,7 @@ Now it's time to fill up the functions that we left empty before.
171184

172185
#### `draw_data()`
173186

174-
This function will convert the elements of `data[]` into vertical bars and draw them into the window.
187+
This function will convert the elements of `data[]` into vertical bars and draw them into the window.
175188

176189
```python
177190
def draw_data(data, colorArray):
@@ -221,7 +234,7 @@ def set_speed():
221234

222235
#### `sort()`
223236

224-
We will import the algorithms in `main.py`.
237+
We will import the algorithms in `main.py`.
225238

226239
```python
227240
from algorithms.bubbleSort import bubble_sort
@@ -231,6 +244,7 @@ from algorithms.insertionSort import insertion_sort
231244
from algorithms.quickSort import quick_sort
232245
from algorithms.countingSort import counting_sort
233246
from algorithms.radixSort import radix_sort
247+
from algorithms.heapSort import heap_sort
234248
```
235249

236250
```python
@@ -251,6 +265,8 @@ def sort():
251265
counting_sort(data, draw_data, time_tick)
252266
elif algorithm_menu.get() == 'Radix Sort':
253267
radix_sort(data, draw_data, time_tick)
268+
elif algorithm_menu.get() == 'Heap Sort':
269+
heap_sort(data, draw_data, time_tick)
254270
else:
255271
pass
256272
```
1.07 KB
Binary file not shown.

algorithms/heapSort.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import time
2+
from colors import *
3+
4+
5+
def heapify(data, n, i, draw_data, time_tick):
6+
largest = i
7+
left = 2*i + 1
8+
right = 2*i + 2
9+
if left < n and data[i] < data[left]:
10+
largest = left
11+
if right < n and data[largest] < data[right]:
12+
largest = right
13+
if largest != i:
14+
data[i], data[largest] = data[largest], data[i]
15+
heapify(data, n, largest, draw_data, time_tick)
16+
17+
18+
def heap_sort(data, draw_data, time_tick):
19+
n = len(data)
20+
for i in range(n-1, -1, -1):
21+
heapify(data, n, i, draw_data, time_tick)
22+
for i in range(n-1, 0, -1):
23+
data[i], data[0] = data[0], data[i]
24+
heapify(data, i, 0, draw_data, time_tick)
25+
draw_data(data, [YELLOW if x == i else BLUE for x in range(n)])
26+
time.sleep(time_tick)
27+
draw_data(data, [BLUE for x in range(len(data))])

images/heap_sort_1.png

20 KB
Loading

images/heap_sort_2.png

5.47 KB
Loading

images/heap_sort_3.png

106 KB
Loading

images/heap_sort_4.png

5.38 KB
Loading

main.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from algorithms.quickSort import quick_sort
1111
from algorithms.countingSort import counting_sort
1212
from algorithms.radixSort import radix_sort
13+
from algorithms.heapSort import heap_sort
1314

1415

1516
root = Tk()
@@ -19,7 +20,16 @@
1920

2021

2122
algorithm_name = StringVar()
22-
algorithm_list = ['Bubble Sort', 'Merge Sort', 'Selection Sort', 'Insertion Sort', 'Quick Sort', 'Counting Sort', 'Radix Sort']
23+
algorithm_list = [
24+
'Bubble Sort',
25+
'Merge Sort',
26+
'Selection Sort',
27+
'Insertion Sort',
28+
'Quick Sort',
29+
'Counting Sort',
30+
'Radix Sort',
31+
'Heap Sort'
32+
]
2333

2434
speed_name = StringVar()
2535
speed_list = ['Fast', 'Medium', 'Slow']
@@ -79,6 +89,8 @@ def sort():
7989
counting_sort(data, draw_data, time_tick)
8090
elif algorithm_menu.get() == 'Radix Sort':
8191
radix_sort(data, draw_data, time_tick)
92+
elif algorithm_menu.get() == 'Heap Sort':
93+
heap_sort(data, draw_data, time_tick)
8294
else:
8395
pass
8496

0 commit comments

Comments
 (0)