Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A fresh PR for issue #5 #23

Merged
merged 4 commits into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
- [Binary Search](./Searching_Algos/Binary_search/Explanation.md)
- [Binary vs Linear Search](./Searching_Algos/Binary_search/binaryVSlinear.md)
- [Ternary Search](./Searching_Algos/Ternary_search/Explanation.md)
- [Sorting Algorithms](./SortingAlgorithms/README.md)
- [Quick Sort](./SortingAlgorithms/QuickSort.md)
- [Radix Sort](./SortingAlgorithms/RadixSort.md)
- [Persistent Data Structure](./PersistentDS/README.md)
- [Persistent Segment Trees](./PersistentDS/persistentST.md)
- [Graph](./Graph/Graph.md)
Expand Down
141 changes: 141 additions & 0 deletions src/SortingAlgorithms/QuickSort.md
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/)
10 changes: 10 additions & 0 deletions src/SortingAlgorithms/README.md
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)
139 changes: 139 additions & 0 deletions src/SortingAlgorithms/RadixSort.md
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/)