---
# System prepended metadata

title: 'Different Sorting Time Test:'

---

# Different Sorting Time Test:
## Insertion sort, Counting sort, Merge sort, and Quick sort ( Lomuto, Hoare, Three way Partition )

程式碼:
```cpp=
#include<iostream>
#include<vector>
#include<time.h>
#include<algorithm>
using namespace std;

enum type{
    Lomuto = 0, Hoare, Three_Way
};

static int partition_Type = 0;

const int Max = 1000;

void printArray(vector<int> &arr, int n);

void insertionSort(vector<int> &arr, int n)
{
    int i, key, j;
    for (i = 1; i < n; i++)
    {
        key = arr[i];
        j = i - 1;

        // Move elements of arr[0..i-1],
        // that are greater than key, to one
        // position ahead of their
        // current position
        while (j >= 0 && arr[j] > key)
        {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

void Merge(std::vector<int> &Array, int front, int mid, int end){

    // 利用 std::vector 的constructor,
    // 把array[front]~array[mid]放進 LeftSub[]
    // 把array[mid+1]~array[end]放進 RightSub[]
    std::vector<int> LeftSub(Array.begin()+front, Array.begin()+mid+1),
                     RightSub(Array.begin()+mid+1, Array.begin()+end+1);

    LeftSub.insert(LeftSub.end(), Max);      // 在LeftSub[]尾端加入值為 Max 的元素
    RightSub.insert(RightSub.end(), Max);    // 在RightSub[]尾端加入值為 Max 的元素

    int idxLeft = 0, idxRight = 0;

    for (int i = front; i <= end; i++) {

        if (LeftSub[idxLeft] <= RightSub[idxRight] ) {
            Array[i] = LeftSub[idxLeft];
            idxLeft++;
        }
        else{
            Array[i] = RightSub[idxRight];
            idxRight++;
        }
    }
}

void MergeSort(std::vector<int> &array, int front, int end){
                                         // front與end為矩陣範圍
    if (front < end) {                   // 表示目前的矩陣範圍是有效的
        int mid = (front+end)/2;         // mid即是將矩陣對半分的index
        MergeSort(array, front, mid);    // 繼續divide矩陣的前半段subarray
        MergeSort(array, mid+1, end);    // 繼續divide矩陣的後半段subarray
        Merge(array, front, mid, end);   // 將兩個subarray做比較, 並合併出排序後的矩陣
    }
}

void countSort(vector<int>& arr)
{
    int max = *max_element(arr.begin(), arr.end());
    int min = *min_element(arr.begin(), arr.end());
    int range = max - min + 1;

    vector<int> count(range), output(arr.size());
    for (int i = 0; i < arr.size(); i++)
        count[arr[i] - min]++;

    for (int i = 1; i < count.size(); i++)
        count[i] += count[i - 1];

    for (int i = arr.size() - 1; i >= 0; i--) {
        output[count[arr[i] - min] - 1] = arr[i];
        count[arr[i] - min]--;
    }

    for (int i = 0; i < arr.size(); i++)
        arr[i] = output[i];
}

int Lomuto_partition(vector<int> &arr, int low, int high);

int Hoare_partition(vector<int> &arr, int low, int high);

void Three_Way_partition(vector<int> &arr, int l, int r, int& i, int& j);


void quickSort(vector<int> &arr, int low, int high)
{
    if (low < high)
    {

        ///Lomuto partition
        if(partition_Type == Lomuto){
            /* pi is partitioning index, arr[p] is now
                at right place */
            int pi = Lomuto_partition(arr, low, high);

            // Separately sort elements before
            // partition and after partition
            quickSort(arr, low, pi - 1);
            quickSort(arr, pi + 1, high);
        }
        ///Hoare partition
        else if(partition_Type == Hoare){
            /* pi is partitioning index, arr[p] is now
                at right place */
            int pi = Hoare_partition(arr, low, high);


            // Separately sort elements before
            // partition and after partition
            quickSort(arr, low, pi - 1);
            quickSort(arr, pi + 1, high);
        }
        ///Three way partition
        else if(partition_Type == Three_Way){
            /* i,j is partitioning index, arr[p] is now
                at right place */
            int i, j;

            // Note that i and j are passed as reference
            Three_Way_partition(arr, low, high, i, j);


            // Separately sort elements before
            // partition and after partition
            quickSort(arr, low, j);
            quickSort(arr, i, high);
        }


    }
}

int Lomuto_partition(vector<int> &arr, int low, int high)
{
    int pivot = arr[high];    // pivot
    int i = (low - 1);  // Index of smaller element

    for (int j = low; j <= high- 1; j++)
    {
        // If current element is smaller than or
        // equal to pivot
        if (arr[j] <= pivot)
        {
            i++;    // increment index of smaller element
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i + 1], arr[high]);
    return (i + 1);
}

int Hoare_partition(vector<int> &arr, int low, int high)
{
    int pivot = arr[low];
    int i = low - 1, j = high + 1;

    while (true) {
        // Find leftmost element greater than
        // or equal to pivot
        do {
            i++;
        } while (arr[i] < pivot);

        // Find rightmost element smaller than
        // or equal to pivot
        do {
            j--;
        } while (arr[j] > pivot);

        // If two pointers met.
        if (i >= j)
            return j;

        swap(arr[i], arr[j]);
    }
}

void Three_Way_partition(vector<int> &arr, int l, int r, int& i, int& j)
{
    i = l - 1, j = r;
    int p = l - 1, q = r;
    int v = arr[r];

    while (true) {
        // From left, find the first element greater than
        // or equal to v. This loop will definitely
        // terminate as v is last element
        while (arr[++i] < v)
            ;

        // From right, find the first element smaller than
        // or equal to v
        while (v < arr[--j])
            if (j == l)
                break;

        // If i and j cross, then we are done
        if (i >= j)
            break;

        // Swap, so that smaller goes on left greater goes
        // on right
        swap(arr[i], arr[j]);

        // Move all same left occurrence of pivot to
        // beginning of array and keep count using p
        if (arr[i] == v) {
            p++;
            swap(arr[p], arr[i]);
        }

        // Move all same right occurrence of pivot to end of
        // array and keep count using q
        if (arr[j] == v) {
            q--;
            swap(arr[j], arr[q]);
        }
    }

    // Move pivot element to its correct index
    swap(arr[i], arr[r]);

    // Move all left same occurrences from beginning
    // to adjacent to arr[i]
    j = i - 1;
    for (int k = l; k < p; k++, j--)
        swap(arr[k], arr[j]);

    // Move all right same occurrences from end
    // to adjacent to arr[i]
    i = i + 1;
    for (int k = r - 1; k > q; k--, i++)
        swap(arr[i], arr[k]);
}

int main(){
    int power_of_2;
    do {
        cout<<"Enter a number(0~20)"<<endl;
        cin>>power_of_2;
    }while(power_of_2>30);

    unsigned int num = 1<<power_of_2;

    cout<<power_of_2<<": "<<num<<endl;

    vector<int> vec[10];

    for(int i=0 ; i<10 ; ++i){
        int countn = num;
        while(countn--){
            int temp = rand()%1000;
            vec[i].push_back(temp);
        }
    }

    clock_t start_t, end_t, average = 0;

    for(int i =0 ; i<10 ; ++i){
        start_t = clock();
        //insertionSort(vec[i],num);
        //MergeSort(vec[i], 0, num-1);
        //countSort(vec[i]);

        {
            //partition_Type = Lomuto;
            //partition_Type = Hoare;
            partition_Type = Three_Way;

            quickSort(vec[i], 0, num-1);
        }


        end_t = clock();
        average+=(end_t-start_t);
    }

    if(power_of_2<=10){
        for(int i =0 ; i<10 ; ++i){
            printArray(vec[i],num);
        }
    }

    cout<<average/10.0<<"ms"<<endl;

}

// A utility function to print an array
// of size n
void printArray(vector<int> &arr, int n)
{
    int i;
    for (i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
}

```