Skip to content

Commit

Permalink
Final HeapSort.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhinav-J05 authored Oct 1, 2022
1 parent 3cc1c7a commit afdecf1
Showing 1 changed file with 103 additions and 199 deletions.
302 changes: 103 additions & 199 deletions tutorials/basic-topics/sorting/heap-sort.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,220 +36,124 @@ Heap Sort:
Before starting using the algorithm, Let's first understand what is "heapify"?

Heapify means creating a heap data structure from a binary tree represented in form of array. We can create a max heap or min heap. Here we will use Max Heap.
One thing to notice here that, we are not making Max heap by conventional method as it will take us O(nlogn) time. we are using heapify which will perform the operation in O(N) time complexity.

pseudo code for heapify :
"
heapify(array)
root = array[0]
largest = largest(array[0], array[2*0+1]/array[2*0+2]
if(root != largest)
swap(root, largest) "

Implementation of Heapify:
Suppose the given array is. arr[] = {1, 3, 5, 4, 6, 13, 10, 9, 8, 15, 17}

now, Binary tree of this will somewhere look like this.

1
/ \
3 5
/ \ / \
4 6 13 10
/ \ / \
9 8 15 17
Next step here is to convert this into Max Heap,
By refering to the heapify algorithm stated above, we can say,
Total Nodes = 11.
Last Non-leaf node index = (11/2) – 1 = 4.
Therefore, last non-leaf node = 6.

To build the heap, heapify only the nodes: [1, 3, 5, 4, 6] in reverse order.
Heapify 6: Swap 6 and 17.

1
/ \
3 5
/ \ / \
4 17 13 10
/ \ / \
9 8 15 6

Heapify 4: Swap 4 and 9.
1
/ \
3 5
/ \ / \
9 17 13 10
/ \ / \
4 8 15 6
Heapify 5: Swap 13 and 5.

1
/ \
3 13
/ \ / \
9 17 5 10
/ \ / \
4 8 15 6

Heapify 3: First Swap 3 and 17, again swap 3 and 15.

1
/ \
17 13
/ \ / \
9 15 5 10
/ \ / \
4 8 3 6

Heapify 1: First Swap 1 and 17, again swap 1 and 15, finally swap 1 and 6.

17
/ \
15 13
/ \ / \
9 6 5 10
/ \ / \
4 8 3 1


Now, let's perform Heap Sort Algorithm for an array.
Suppose the array is arr[] = {4, 10, 3, 5, 1}

Build Complete Binary Tree: Build a complete binary tree from the array.
![image](https://user-images.githubusercontent.com/86758548/193395993-aca6d3d5-b15d-4288-b5d8-9286cebdcccb.png)

Transform into max heap: After that, the task is to construct a tree from that unsorted array and try to convert it into Max Heap.
To transform a heap into a max-heap, the parent node should always be greater than or equal to the child nodes
Here, in this example, as the parent node 4 is smaller than the child node 10, thus, swap them to build a max-heap.
Now, as seen, 4 as a parent is smaller than the child 5, thus swap both of these again and the resulted heap and array should be like this:
![image](https://user-images.githubusercontent.com/86758548/193396040-6c77425f-95ce-4162-abe3-6b0fb8d5e5b4.png)
HEAPIFY ALGORITHM :
1. check for left child if it's greater than the parent.
2. check for right child if it's grater than the parent.
3. if any of the above is true, make that child as largest.
4. now, check if "largest" is the same as "i" (starting node), if it is not then swap.
5. repeat the above process, recursively.

Perform heap sort: Remove the maximum element in each step (i.e., move it to the end position and remove that) and then consider the remaining elements and transform it into a max heap.
Now that we have understood both Heapify and Heap Sort Algoirthm, let us try an example to strengthen the concept.

Delete the root element (10) from the max heap. In order to delete this node, try to swap it with the last node, i.e. (1). After removing the root element, again heapify it to convert it into max heap.
Problem Statement:
Given an array of integers nums, sort the array in ascending order and return it.
You must solve the problem without using any built-in functions in O(nlog(n)) time complexity and with the smallest space complexity possible.

Resulted heap and array should look like:
![image](https://user-images.githubusercontent.com/86758548/193396057-0e54f6a4-0751-4bb1-8cd4-d502929efa00.png)
Link of above leetcode problem : https://leetcode.com/problems/sort-an-array/

Repeat the above steps and it will look like the following:
![image](https://user-images.githubusercontent.com/86758548/193396076-f7acf966-0ab5-4a12-956a-b86633ddb9ba.png)
Answer :

ow remove the root (i.e. 3) again and perform heapify.
![image](https://user-images.githubusercontent.com/86758548/193396081-703aefd7-28f3-4a14-9ab5-a8f9b9e3e371.png)
alright, let's take the given input 2 array

Now when the root is removed once again it is sorted. and the sorted array will be like arr[] = {1, 3, 4, 5, 10}.
![image](https://user-images.githubusercontent.com/86758548/193396091-188f3e0a-c21f-4d60-972a-d278e65f3ac3.png)
nums = [5,1,1,2,0,0]

That's it! You have Learned the Heap Sort.

Now Coming to the Code part, here is the C++ inplementation of Heap Sort.
Binary Tree for this array will look like :
5
/ \
2 1 here, as we can see this is a max heap.
/ \ /
1 0 0

Now, next step is, Remove the max element.
{ Here, removing means, swapping the max element with last one. and then we will call the function again, this time ignoring the last element.}

C++:
After this tree will look like,

/* To heapify a subtree rooted with node i
which is an index in arr[].
n is size of heap */

void heapify(int arr[], int N, int i)
{
// Initialize largest as root
int largest = i;

// left = 2*i + 1
int l = 2 * i + 1;

// right = 2*i + 2
int r = 2 * i + 2;

// If left child is larger than root
if (l < N && arr[l] > arr[largest])
largest = l;

// If right child is larger than largest
// so far
if (r < N && arr[r] > arr[largest])
largest = r;

// If largest is not root
if (largest != i) {
swap(arr[i], arr[largest]);

// Recursively heapify the affected
// sub-tree
heapify(arr, N, largest);
}
}

// Main function to perform Heap sort
void heapSort(int arr[], int N)
{

// Build heap (rearrange array)
for (int i = N / 2 - 1; i >= 0; i--)
heapify(arr, N, i);
0
/ \
2 1 here, as we can see this is not a max Heap, so now we will heapify it again.
/ \
1 0
array now : {0,2,1,1,0, 5}

// One by one extract an element
// from heap
for (int i = N - 1; i > 0; i--) {
After Heapifying:

// Move current root to end
swap(arr[0], arr[i]);
2
/ \
1 1
/ \
0 0

Here, 0 and 2 were swapped and next time, 1 and 0 were also swapped to make it a max heap.
array now : {2,1,1,0,0, 5}

Now, again removing the Max element { swapping in real }

tree becomes :

0
/ \
1 1 here, as we can see this is not a max Heap, so now we will heapify it again.
/
0

after Heapifying :

1
/ \
0 1 Now, in next step wwe will remove the max element again.
/
0
array now : {1,0,1,0, 2, 5}


Same steps repeats.
And finally we will get our sorted array.

Now as you can see, performing these operations recursively we could achieve our sorted array easily.

Let's code this algorithm,<br>
For this we will be using 3 functions.<br>
one utility function named Heapify, to heapify a tree ( subtree in reality ) with root node "i".<br>
one function to do the heap sort.<br>
one final function to sort the array.<br>
<br>

```
void heapify( vector<int> &arr, int n, int i){
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;
if(l<n and arr[l] > arr[largest])
largest = l;
if(r<n and arr[r] > arr[largest])
largest = r;
if(largest!=1){
swap(arr[i], arr[largest]);
heapify(arr,n,largest);
}
}
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// A utility function to print array of size n
void printArray(int arr[], int N)
{
for (int i = 0; i < N; ++i)
cout << arr[i] << " ";
cout << "\n";
}

Last but not least, let's try to solve a Leetcode Problem.

Problem Statement : Given an array nums with n objects colored red, white, or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white, and blue.
We will use the integers 0, 1, and 2 to represent the color red, white, and blue, respectively.
You must solve this problem without using the library's sort function.

Implementation:
// Here i have used HeapDown and Dequeue for using a different approach, otherwise this could be done using simple two pointer also.

void HeapDown(int index, int size, vector<int>& nums) {
if (2*index+1 >= size) return;

int leftChild = 2*index+1;
int rightChild = 2*index+2;
int chosenChild;
if (leftChild < size && nums[leftChild] <= nums[rightChild]) chosenChild = leftChild;
if (rightChild < size && nums[rightChild] <= nums[chosenChild]) chosenChild = rightChild;

if (nums[chosenChild] < nums[index]) {
swap(nums[chosenChild], nums[index]);
HeapDown(chosenChild, size, nums);
// this function will start from n/2-1, because (n/2-1)th node will be the last non-leaf node...after that all nodes will be leaf nodes, which eventually means they are already max heap.
void buildHeap(vector<int>& arr, int n){
for(int i=n/2-1; i>=0; i--){
heapify(arr,n,i);
}
else return;
}
int Dequeue(vector<int>& nums, int size) {
if (size == 0) return -999;
int res = nums[0];
nums[0] = nums[size-1];
HeapDown(0, size, nums);
return res;
}
void sortColors(vector<int>& nums) {
int size = 0;
vector<int> res;
for (int i = nums.size()-1; i >= 0; i--) {
HeapDown(i, nums.size(), nums);
size++;
}
for (int i = 0; i < size+i; i++) {
res.push_back(Dequeue(nums,size));
size--;
vector<int> sortArray(vector<int>& arr) {
int n = arr.size();
buildHeap(arr,n);<br>
for(int i=n-1; i>0; i--){
swap(arr[0],arr[i]);
heapify(arr,i,0);
}
nums = res;
return arr;
}
```


0 comments on commit afdecf1

Please sign in to comment.