forked from codeIIEST/Algorithms
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from Anirbansikder/changes_issue5
Quick Sort and Radix Sort
- Loading branch information
Showing
4 changed files
with
293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
# Quick Sort | ||
|
||
## Example Problem | ||
|
||
Given an array ``arr = [a1,a2,a3,a4,a5...,an] `` , we need to sort the array the array with the help of Quick Sort algorithm. | ||
|
||
<hr> | ||
|
||
## Discussion | ||
|
||
So the basic idea behind Quick Sort is to take an element generally called the **pivot** and place it at such a place such that it is in it's sorted position. | ||
|
||
Look at the following list of numbers: | ||
``` | ||
10 36 15 23 56 12 | ||
``` | ||
Can you guess the number at the sorted position ? Yes it can be identified by just at glance , that is 10. | ||
|
||
Now Let's take another example: | ||
|
||
``` | ||
40 36 15 50 75 62 57 | ||
``` | ||
Now we can see that 50 is at it's sorted poition by just a glance. | ||
This is because all the elements before it is less than 50 and all elemnts after it is greater than 50. | ||
|
||
So , the main idea is to select a **pivot** and place it to it's sorted position. | ||
|
||
<hr> | ||
|
||
## Working of the Algorithm | ||
|
||
Let us take an example with the list of integers | ||
``` | ||
50 70 60 90 40 80 10 20 30 | ||
``` | ||
Let us take the first element to be pivot that is 50. | ||
|
||
Take two pointers ``i , j`` . Initially place ``i`` at the pivot i.e. index 0 and ``j`` at position n and keep a number (say infinite) at index n. | ||
|
||
So, it looks like : | ||
``` | ||
50 70 60 90 40 80 10 20 30 INT_MAX | ||
i j | ||
``` | ||
|
||
Now iterate i towards right and j towards left . Stop when ``arr[i]>pivot`` and ``arr[j]<=pivot`` . If ``i < j`` swap the values . Continue the process until `i>j` . Whwn this case arrives swap the **pivot** with ``arr[j]``. | ||
|
||
### Illustration | ||
|
||
``` | ||
50 70 60 90 40 80 10 20 30 INT_MAX | ||
i j | ||
// Here arr[i]>=50 and arr[j]<50 , so we swap them and move the pointers since i<j. | ||
50 30 60 90 40 80 10 20 70 INT_MAX | ||
i j | ||
// Swapping again , and moving pointers. | ||
50 30 20 90 40 80 10 60 70 INT_MAX | ||
i j | ||
// Swapping again , and moving pointers. | ||
50 30 20 10 40 80 90 60 70 INT_MAX | ||
j i | ||
// Now we see j<i , so we stop the loop and swap arr[j] with pivot. | ||
40 30 20 10 50 80 90 60 70 INT_MAX | ||
__ | ||
``` | ||
Now , we see that all elements before 50 are lesser than 50 and all elemnts after 50 are greater than 50. | ||
|
||
Now apply this partitioning on both sides of 50 and hence, we will get our sorted array. | ||
|
||
<hr> | ||
|
||
## Code | ||
|
||
### Code For Partition | ||
```cpp | ||
int partition(int a[],int l ,int h) | ||
{ | ||
int pivot = a[l]; // choosing left-most elemnt to be pivot | ||
int i=l,j=h; // setting pointers i and j | ||
|
||
//looping through the process until we get j<i | ||
do{ | ||
// iterating i until we get a number greater than pivot | ||
while(a[++i]<=pivot); | ||
|
||
// iterating j until we get a number greater than pivot | ||
while(a[--j]>pivot); | ||
|
||
//swapping arr[i] and arr[j] | ||
if(i<j){ | ||
swap(a[i],a[j]); | ||
} | ||
}while(i<j); | ||
|
||
// swapping pivot | ||
swap(a[j],a[l]); | ||
|
||
//return partition point | ||
return j; | ||
} | ||
``` | ||
### Code for Quick Sort. | ||
```cpp | ||
void QuickSort(int a[],int l,int h) | ||
{ | ||
int j; | ||
if(l<h) | ||
{ | ||
j=partition(a,l,h); // taking the partition point | ||
QuickSort(a,l,j); // Sorting the left side | ||
QuickSort(a,j+1,h); // Sorting right side | ||
} | ||
} | ||
``` | ||
<hr> | ||
|
||
## Time Complexity | ||
|
||
|
||
| Worst Case | Best Case | Average Case | | ||
|:-----------------:|:-----------------:|:-----------------:| | ||
| O ( n<sup>2</sup> ) | O ( nlog<sub>2</sub>n ) | O ( nlog<sub>2</sub>n ) | | ||
|
||
**Worst Case** : The worst case occurs when the partition process always picks greatest or smallest element as pivot. If we consider above partition strategy where first element is always picked as pivot, the worst case would occur when the array is already sorted in increasing or decreasing order. | ||
|
||
**Best Case**: The best case occurs when the partition process always picks the middle element as pivot. | ||
|
||
<hr> | ||
|
||
Other Resources : [GFG Blog](https://www.geeksforgeeks.org/quick-sort/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Sorting Algorithms | ||
|
||
A Sorting Algorithm is used to rearrange a given array or list elements according to a comparison operator on the elements. The comparison operator is used to decide the new order of element in the respective data structure. | ||
|
||
<hr> | ||
|
||
## Topics Covered | ||
|
||
- [Quick Sort](./QuickSort.md) | ||
- [Radix Sort](./RadixSort.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# Radix Sort | ||
|
||
## Example Problem | ||
|
||
Given an array ``arr = [a1,a2,a3,a4,a5...,an] `` , we need to sort the array the array with the help of Radix Sort algorithm. | ||
|
||
<hr> | ||
|
||
## Discussion | ||
|
||
Since you are reading this , I assume that you have already gone through most of the comparison sorts that is `Merge Sort , Quick Sort , etc` . Problem with comparison based algorithm is that the lower bound complexity for them is `nlogn`. They cannot do better than that. | ||
|
||
`Counting Sort , Bin Bucket Sort ` can be used to tackle this problem , but problem with counting sort is that if the maximum number in the array is of the order n<sup>2</sup> , then the running time complexity would be of the order O(n<sup>2</sup>). Also the extra space required increases with the maximum number. | ||
|
||
The idea of `Radix Sort` is to do digit by digit sort starting from least significant digit to most significant digit. Radix sort uses counting sort as a subroutine to sort. | ||
|
||
<hr> | ||
|
||
## Working of the Algorithm | ||
|
||
Do following for each digit i where i varies from least significant digit to the most significant digit. | ||
- Sort input array using counting sort (or any stable sort) according to the i’th digit. | ||
- Update The array. | ||
|
||
--------------- | ||
|
||
### Illustration | ||
|
||
Let us look at the following illustration : | ||
|
||
``` | ||
23 20 15 5 61 301 17 33 | ||
Let's look at the one's position for each of the numbers. | ||
23 20 15 5 61 301 17 33 | ||
_ _ _ _ _ _ _ _ | ||
Sort them according to the marked digits. If there are same digits put them from left to right according to the array. | ||
20 61 301 23 33 15 05 17 | ||
_ _ _ _ _ _ _ _ | ||
Sort them again according to Ten's place. | ||
301 005 015 017 020 023 033 061 | ||
_ _ _ _ _ _ _ _ | ||
Sort them again according to Hundred's place. | ||
005 015 017 020 023 033 061 301 | ||
We get the final sorted array. | ||
5 15 17 20 23 33 61 301 | ||
``` | ||
|
||
<hr> | ||
|
||
## Code | ||
|
||
### Code For Sorting according to digits | ||
```cpp | ||
void digit_sort(int a[],int n,int exp) | ||
{ | ||
// declaring vector array of size 10. Since there are 10 digits. | ||
vector <int> arr[10]; | ||
|
||
// pushing each number in their respective buckets. | ||
for(int i=0;i<n;i++){ | ||
arr[ (a[i]/exp) % 10 ].push_back(a[i]); | ||
} | ||
|
||
int j = 0; | ||
|
||
// Updating the main array. | ||
for(int i=0;i<10;i++) | ||
{ | ||
for(auto x:arr[i]){ | ||
a[j] = x; | ||
j++; | ||
} | ||
} | ||
|
||
// deleting the extra space. | ||
for(int i=0;i<10;i++) | ||
arr[i].clear(); | ||
} | ||
``` | ||
### Code for Radix Sort. | ||
```cpp | ||
void RadixSort(int a[],int n) | ||
{ | ||
// function for finding the max digit | ||
int m = max_digit(a,n); | ||
for(int i=1;i<=m;i++) | ||
{ | ||
// digit_sort for each place | ||
digit_sort(a,n,int(pow(10,i-1)+0.5)); | ||
} | ||
} | ||
``` | ||
|
||
### Code for finding maximum number of digits. | ||
```cpp | ||
int max_digit(int a[], int n) | ||
{ | ||
int res = 0; | ||
for(int i=0;i<n;i++) | ||
{ | ||
int temp = a[i] , count = 0; | ||
while(temp) | ||
{ | ||
temp/=10; | ||
count++; | ||
} | ||
res = max(res,count); | ||
} | ||
return res; | ||
} | ||
``` | ||
------------- | ||
## Time Complexity | ||
### What is the running time of Radix Sort? | ||
Let there be d digits in input integers. Radix Sort takes `O(d*(n+b))` time where `b` is the base for representing numbers, for example, for the decimal system, b is 10. What is the value of d? If k is the maximum possible value, then d would be `O(logb(k))`. So overall time complexity is `O((n+b) * logb(k))`. Which looks more than the time complexity of comparison-based sorting algorithms for a large k. Let us first limit k. Let k <= nc where c is a constant. In that case, the complexity becomes O(nLogb(n)). But it still doesn’t beat comparison-based sorting algorithms. | ||
### What if we make the value of b larger?. | ||
What should be the value of b to make the time complexity linear? If we set b as n, we get the time complexity as `O(n)`. In other words, we can sort an array of integers with a range from 1 to nc if the numbers are represented in base n (or every digit takes `log2(n)` bits). | ||
<hr> | ||
Other Resources : [GFG Blog](https://www.geeksforgeeks.org/radix-sort/) |