Skip to content
Open
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
63 changes: 63 additions & 0 deletions Algorithms/Sort/MergeSort/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Merge Sort
MergeSort is a robust sorting algorithm that divides an array into smaller halves, sorts each half independently, and then merges them back together. It ensures reliable and consistent performance, making it suitable for a wide range of applications.

## Pseudocode
```plaintext
function mergeSort(array):
if array.length() > 1:
mid = array.length() / 2
left = array[0...mid-1]
right = array[mid...]

# Recursively sort the two halves
mergeSort(left)
mergeSort(right)

# Merge the sorted halves
merge(array, left, right)

function merge(array, left, right):
i = j = k = 0

while i < left.length() and j < right.length():
if left[i] <= right[j]:
array[k] = left[i]
i = i + 1
else:
array[k] = right[j]
j = j + 1
k = k + 1

# Copy remaining elements if any
while i < left.length():
array[k] = left[i]
i = i + 1
k = k + 1

while j < right.length():
array[k] = right[j]
j = j + 1
k = k + 1
```

## Time & Space Complexity
|Case |Time |Space |
|--------|:---------------|:-----|
|Best |Ω(n log(n) |Ω(n) |
|Average |Θ(n log(n) |Θ(n) |
|Worst |O(n log(n) |O(n) |

## Variants
- Bottom-Up MergeSort
- Natural MergeSor

## Use Cases
- Efficient for sorting large datasets consistently.
- Frequently used in scenarios where stable sorting is required.
- Suitable for scenarios with linked lists due to its sequential access.

## Best Practice
- Offers consistent performance across different scenarios.
- Well-suited for handling large datasets efficiently.
- Preferred for scenarios where stability in sorting order is important.
- Efficiently works with linked lists due to its sequential nature.
90 changes: 90 additions & 0 deletions Algorithms/Sort/QuickSort/QuickSort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <iostream>
#include <vector>

/**
* @brief Swap two elements in a vector.
*
* This function swaps the elements at positions `i` and `j` in the provided vector.
*
* @param i Index of the first element to be swapped.
* @param j Index of the second element to be swapped.
* @param array Reference to the vector containing elements.
*/
void swap(int i, int j, std::vector<int>& array) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}

/**
* @brief Partition the elements into two parts around the pivot
* This function arrange the elements of array into tow parts around the pivot
*
* @param array Reference to the vector containing elements.
* @param low Lowest index of the array.
* @param high Highest index of the array.
* @return int The pivot around which the elements are partitioned.
*/
int partition(std::vector<int>& array, int low, int high) {
// Choose the rightmost element as the pivot
int pivot = array[high];
int i = low - 1;

// Iterate through the array to rearrange elements
for(int j = low; j <= high - 1; j++) {
if(array[j] <= pivot) {
i = i + 1;
swap(i, j, array);
}
}

// Place the pivot in its correct position
swap(i + 1, high, array);
return i + 1;
}

/**
* @brief Perform Quick Sort on a vector.
*
* This function sorts the elements of the vector in ascending order using the
* Quick Sort algorithm.
*
* @param array Reference to the vector to be sorted.
* @param low Reference to the lowest index of the array.
* @param high Reference to the highest index of the array.
*/
void quickSort(std::vector<int>& array, int low, int high) {
if(low < high) {
// Partion the array into two segments
int pivotIndex = partition(array, low, high);

// Recursively sort the two segments
quickSort(array, low, pivotIndex -1);
quickSort(array, pivotIndex + 1, high);
}
}


int main() {
// Example usage
std::vector<int> myArray = {-1, -5, -7, 6, 1, 0, 0, 4, 1, 12, 100};

// Print the original array
std::cout << "Original array: ";
for (int elem : myArray) {
std::cout << elem << " ";
}
std::cout << std::endl;

// Sort the array using bubble sort
quickSort(myArray, 0, myArray.size()-1);

// Print the sorted array
std::cout << "Sorted array: ";
for (int elem : myArray) {
std::cout << elem << " ";
}
std::cout << std::endl;

return 0;
}
56 changes: 56 additions & 0 deletions Algorithms/Sort/QuickSort/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Quick Sort
Quick Sort is a powerful sorting algorithm that efficiently sorts an array by dividing it into smaller segments. It's known for its speed and is often used in real-world applications. Unlike `Insertion Sort`, Quick Sort doesn't build the sorted array one element at a time; instead, it divides the array into smaller segments, sorts them independently, and then combines them.

## Pseudocode
```plaintext
function quickSort(array, low, high):
if low < high:
# Partition the array into two segments
pivotIndex = partition(array, low, high)

# Recursively sort the two segments
quickSort(array, low, pivotIndex - 1)
quickSort(array, pivotIndex + 1, high)

function partition(array, low, high):
# Choose the rightmost element as the pivot
pivot = array[high]
i = low - 1

# Iterate through the array to rearrange elements
for j = low to high - 1:
if array[j] <= pivot:
i = i + 1
swap(array, i, j)

# Place the pivot in its correct position
swap(array, i + 1, high)
return i + 1

function swap(array, i, j):
temp = array[i]
array[i] = array[j]
array[j] = temp
```

## Time & Space Complexity
|Case |Time |Space |
|:-------|:---------------|:--------|
|Best |Ω(n log(n)) |Ω(log(n))|
|Average |Θ(n log(n)) |Θ(log(n))|
|Worst |O(n<sup>2</sup>)|O(log(n))|

## Variants
- Randomized QuickSort
- Hybrid QuickSort (combining QuickSort with another sorting algorithm for small segments)

## Use Cases
- Highly effective for sorting large datasets efficiently.
- Frequently used in various programming libraries and languages.
- Well-suited for scenarios where speed is crucial.

## Best Practice
- Efficient for large datasets, outperforms algorithms like `Insertion Sort` for big tasks.
- Implementing randomized versions helps avoid worst-case scenarios.
- Consider the hybrid version for increased efficiency with smaller datasets.
- Well-suited for scenarios where elements are scattered throughout the array.