mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-04-10 22:18:06 +08:00
made more C-plus-plusy
This commit is contained in:
@@ -1,91 +1,125 @@
|
||||
/*
|
||||
*Author: immortal-j
|
||||
*Implementation Details
|
||||
*Quick sort 3 works on Dutch National Flag Algorithm
|
||||
*The major diffrence between simple quicksort and quick sort 3 comes in the
|
||||
*function partition3 In quick_sort_partition3 we divide the vector/array into 3
|
||||
*parts. quick sort 3 works faster in some cases as compared to simple quicksort.
|
||||
*/
|
||||
* @file
|
||||
* @brief Implementation Details
|
||||
* @details Quick sort 3 works on Dutch National Flag Algorithm
|
||||
* The major difference between simple quicksort and quick sort 3 comes in the
|
||||
* function partition3 In quick_sort_partition3 we divide the vector/array into
|
||||
* 3 parts. quick sort 3 works faster in some cases as compared to simple
|
||||
* quicksort.
|
||||
* @author immortal-j
|
||||
* @author [Krishna Vedala](https://github/kvedala)
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
// function to swap elements
|
||||
void swap(int *a, int *b) {
|
||||
int temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* Operator to print the array.
|
||||
* @param out std::ostream object to write to
|
||||
* @param arr array to write
|
||||
*/
|
||||
template <typename T, size_t size>
|
||||
std::ostream &operator<<(std::ostream &out, const std::array<T, size> &arr) {
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
out << arr[i];
|
||||
if (i < size - 1) {
|
||||
out << ", ";
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// function to print an array
|
||||
void print_arr(int arr[], int n) {
|
||||
for (int i = 0; i < n; ++i){
|
||||
std::cout << arr[i] << " ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/* This function partitions arr[] in three parts
|
||||
*a) arr[l..i] contains all elements smaller than pivot
|
||||
*b) arr[i+1..j-1] contains all occurrences of pivot
|
||||
*c) arr[j..r] contains all elements greater than pivot
|
||||
*/
|
||||
void partition3(int arr[], int low, int high, int *i, int *j) {
|
||||
// To handle 2 elements
|
||||
if (high - low <= 1) {
|
||||
if (arr[high] < arr[low]){
|
||||
swap(&arr[high], &arr[low]);
|
||||
/**
|
||||
* @namespace sorting
|
||||
* @brief Sorting Algorithms
|
||||
*/
|
||||
namespace sorting {
|
||||
/** This function partitions `arr[]` in three parts
|
||||
* 1. \f$arr[l\ldots i]\f$ contains all elements smaller than pivot
|
||||
* 2. \f$arr[(i+1)\ldots (j-1)]\f$ contains all occurrences of pivot
|
||||
* 3. \f$arr[j\ldots r]\f$ contains all elements greater than pivot
|
||||
*/
|
||||
template <typename T, size_t N>
|
||||
void partition3(std::array<T, N> *arr, int low, int high, int *i, int *j) {
|
||||
// To handle 2 elements
|
||||
if (high - low <= 1) {
|
||||
if ((*arr)[high] < (*arr)[low]) {
|
||||
std::swap((*arr)[high], (*arr)[low]);
|
||||
}
|
||||
*i = low;
|
||||
*j = high;
|
||||
return;
|
||||
}
|
||||
*i = low;
|
||||
*j = high;
|
||||
return;
|
||||
}
|
||||
|
||||
int mid = low;
|
||||
int pivot = arr[high];
|
||||
while (mid <= high) {
|
||||
if (arr[mid] < pivot){
|
||||
swap(&arr[low++], &arr[mid++]);
|
||||
int mid = low;
|
||||
int pivot = arr[high];
|
||||
while (mid <= high) {
|
||||
if ((*arr)[mid] < pivot) {
|
||||
std::swap((*arr)[low++], (*arr)[mid++]);
|
||||
} else if ((*arr)[mid] == pivot) {
|
||||
mid++;
|
||||
} else if ((*arr)[mid] > pivot) {
|
||||
std::swap((*arr)[mid], (*arr)[high--]);
|
||||
}
|
||||
}
|
||||
else if (arr[mid] == pivot){
|
||||
mid++;
|
||||
}
|
||||
else if (arr[mid] > pivot){
|
||||
swap(&arr[mid], &arr[high--]);
|
||||
}
|
||||
}
|
||||
|
||||
// update i and j
|
||||
*i = low - 1;
|
||||
*j = mid; // or high-1
|
||||
// update i and j
|
||||
*i = low - 1;
|
||||
*j = mid; // or high-1
|
||||
}
|
||||
|
||||
// 3-way partition based quick sort
|
||||
void quicksort(int arr[], int low, int high) {
|
||||
if (low >= high){ // 1 or 0 elements
|
||||
return;
|
||||
template <typename T, size_t N>
|
||||
void quicksort(std::array<T, N> *arr, int low, int high) {
|
||||
if (low >= high) { // 1 or 0 elements
|
||||
return;
|
||||
}
|
||||
|
||||
int i, j;
|
||||
|
||||
// i and j are passed as reference
|
||||
partition3(arr, low, high, &i, &j);
|
||||
|
||||
// Recur two halves
|
||||
quicksort(arr, low, i);
|
||||
quicksort(arr, j, high);
|
||||
}
|
||||
|
||||
int i, j;
|
||||
template <typename T, size_t N>
|
||||
std::array<T, N> quicksort(std::array<T, N> arr, int low, int high) {
|
||||
if (low >= high) { // 1 or 0 elements
|
||||
return;
|
||||
}
|
||||
|
||||
// i and j are passed as reference
|
||||
partition3(arr, low, high, &i, &j);
|
||||
int i, j;
|
||||
|
||||
// Recur two halves
|
||||
quicksort(arr, low, i);
|
||||
quicksort(arr, j, high);
|
||||
// i and j are passed as reference
|
||||
partition3(&arr, low, high, &i, &j);
|
||||
|
||||
// Recur two halves
|
||||
quicksort(&arr, low, i);
|
||||
quicksort(&arr, j, high);
|
||||
|
||||
return arr;
|
||||
}
|
||||
} // namespace sorting
|
||||
|
||||
// Driver program for above functions
|
||||
int main() {
|
||||
int size, i;
|
||||
std::cout << "Enter Number of elements\n";
|
||||
std::cin >> size;
|
||||
int *arr = new int[size];
|
||||
for (i = 0; i < size; i++) {
|
||||
std::cin >> arr[i];
|
||||
}
|
||||
quicksort(arr, 0, size - 1);
|
||||
std::cout << "Sorted Array is:";
|
||||
print_arr(arr, size);
|
||||
std::cout << "\n";
|
||||
return 0;
|
||||
int size, i;
|
||||
std::cout << "Enter Number of elements\n";
|
||||
std::cin >> size;
|
||||
std::array<int, size> arr{};
|
||||
for (auto &a : arr) {
|
||||
a = std::rand() % 100 - 50; // random numbers between -50, 49
|
||||
}
|
||||
|
||||
std::array<int, size> sorted = sorting::quicksort(arr, 0, size - 1);
|
||||
std::cout << "Sorted Array is:\n\t";
|
||||
std::cout << sorted << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user