Created
August 2, 2019 17:52
-
-
Save shajeen/7b40cdb0006e0cb4c344c4aa2ce78bc6 to your computer and use it in GitHub Desktop.
c++11 standard sorting algorithm implementation
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
// sort.cpp : Defines the entry point for the console application. | |
// | |
#include <array> | |
#include <random> | |
#include <iostream> | |
#include <functional> | |
#include <chrono> | |
#include <string> | |
#include <algorithm> | |
#include <thread> | |
///< size of array | |
#define ARRAY_SIZE 12000 | |
///< random number generator up to | |
#define NUM_GEN 100 | |
///< enable if debug message require | |
//#define DEBUG_MESSAGE 1 | |
typedef long NumericType; | |
using namespace std; | |
/// get randome number | |
template <typename T, T iSize> | |
std::array<T, iSize> getRandomNumber() noexcept | |
{ | |
std::random_device rd; | |
std::mt19937 gen(rd()); | |
std::uniform_int_distribution<> dist(0, NUM_GEN); | |
std::array<T, iSize> tempArray; | |
for (T i = 0; i < iSize; ++i) { | |
tempArray[i] = (dist(gen)); | |
} | |
return tempArray; | |
} | |
/* Bubble sort */ | |
template <typename T, T iSize> | |
std::array<T, iSize> bubbleSort(const std::array<T, iSize>& arrayList) | |
{ | |
std::array<T, iSize> temp = arrayList; | |
if (!temp.empty()) { | |
for (T i = 0; i < temp.size(); ++i) { | |
for (T j = 0; j < temp.size(); ++j) { | |
if (temp[i] < temp[j]) { | |
std::swap(temp[i], temp[j]); | |
} | |
} | |
} | |
} | |
return temp; | |
} | |
/* Selection Sort */ | |
template <typename T, T iSize> | |
std::array<T, iSize> SelectionSort(const std::array<T, iSize>& arrayList) | |
{ | |
std::array<T, iSize> temp = arrayList; | |
if (!temp.empty()) { | |
for (T i = 0; i < iSize; ++i) { | |
auto iSwapIndex = i; | |
for (T j = i; j < iSize; ++j) { | |
if (temp[iSwapIndex] > temp[j]) { | |
iSwapIndex = j; | |
} | |
} | |
if (iSwapIndex > 0) { | |
std::swap(temp[i], temp[iSwapIndex]); | |
} | |
} | |
} | |
return temp; | |
} | |
/* Insertion Sort */ | |
template<typename T, T iSize> | |
std::array<T, iSize> InsertionSort(const std::array<T, iSize>& arrayList) | |
{ | |
std::array<T, iSize> temp = arrayList; | |
if (!temp.empty()) { | |
for (T i = 1; i < temp.size(); ++i) { | |
for (T j = 0; j < i; ++j) { | |
if (temp[j] > temp[i]) { | |
std::swap(temp[i], temp[j]); | |
} | |
} | |
} | |
} | |
return temp; | |
} | |
/* Heap Sort */ | |
template<typename T, T iSize> | |
std::array<T, iSize> HeapSort(const std::array<T, iSize>& arrayList) | |
{ | |
std::array<T, iSize> temp = arrayList; | |
if (!temp.empty()) { | |
std::function<void(const T iSize_, const T &iValue)> heapify = [&](const T iSize_, const T &iValue) { | |
auto iLarge = iValue; | |
auto left = 2 * iValue; | |
auto right = 2 * iValue + 1; | |
if ((left < iSize_) && (temp[left] > temp[iLarge])) { | |
iLarge = left; | |
} | |
if ((right < iSize_) && (temp[right] > temp[iLarge])) { | |
iLarge = right; | |
} | |
if (iLarge != iValue) { | |
std::swap(temp[iValue], temp[iLarge]); | |
heapify(iSize_, iLarge); | |
} | |
}; | |
for (T i = iSize / 2; i >= 0; --i) { | |
heapify(iSize, i); | |
} | |
for (T i = iSize - 1; i >= 0; --i) { | |
std::swap(temp[0], temp[i]); | |
heapify(i, 0); | |
} | |
} | |
return temp; | |
} | |
/* Merge Sort */ | |
template<typename T, T iSize> | |
std::array<T, iSize> MergeSort(const std::array<T, iSize>& arrayList) | |
{ | |
std::array<T, iSize> tempMerged = arrayList; | |
auto iLength = 0; | |
function<void(const T &iStart, const T &iMid, const T &iEnd)> mergeArray = [&](const T &iStart, const T &iMid, const T &iEnd) { | |
auto iLocalStart = iStart; | |
auto iLocalMiddle = iMid+1; | |
auto iPosition = 0; | |
std::array<T, iSize> temp; | |
for (auto i = iStart; i <= iEnd; ++i) | |
{ | |
if (iLocalStart > iMid) { | |
temp[iPosition++] = tempMerged[iLocalMiddle++]; | |
} else if (iLocalMiddle > iEnd) { | |
temp[iPosition++] = tempMerged[iLocalStart++]; | |
} else if (tempMerged[iLocalStart] < tempMerged[iLocalMiddle]) { | |
temp[iPosition++] = tempMerged[iLocalStart++]; | |
} else { | |
temp[iPosition++] = tempMerged[iLocalMiddle++]; | |
} | |
} | |
auto iStartM = iStart; | |
for (auto i = 0; i < iPosition; ++i) { | |
tempMerged[iStartM++] = temp[i]; | |
} | |
}; | |
function<void(const T &iStart, const T &iEnd)> mergeSort = [&](const T &iStart, const T &iEnd) { | |
if (iStart < iEnd) { | |
const auto iMiddleValue = (iEnd+iStart)/2; | |
mergeSort(iStart, iMiddleValue); | |
mergeSort(iMiddleValue+1, iEnd); | |
mergeArray(iStart, iMiddleValue, iEnd); | |
} | |
}; | |
mergeSort(iLength, iSize); | |
return tempMerged; | |
} | |
int main() | |
{ | |
typedef std::function<std::array<NumericType, ARRAY_SIZE>(const std::array<NumericType, ARRAY_SIZE>& arrayList)> templateFunctionWrapper; // template function wrapper | |
typedef std::array<NumericType, ARRAY_SIZE> standardArrayWrapper; // array wrapper | |
typedef std::chrono::high_resolution_clock clockWrapper; // clock wrapper | |
clockWrapper::time_point beforeExecution{}; | |
clockWrapper::time_point afterExecution{}; | |
// get random numbers | |
standardArrayWrapper intArray = getRandomNumber<NumericType, ARRAY_SIZE>(); | |
std::cout << "Input: " << std::endl; | |
// print array type | |
std::function<void(standardArrayWrapper)> printArray = [](const standardArrayWrapper intArray) { | |
std::for_each(intArray.begin(), intArray.end(), [](NumericType iVal) { | |
std::cout << iVal << " "; | |
}); | |
std::cout << std::endl; | |
}; | |
// calculate time taken | |
std::function<void(clockWrapper::time_point t1, clockWrapper::time_point t2)> timeCalculate = []( clockWrapper::time_point t1, clockWrapper::time_point t2) { | |
std::cout << "\nTime taken: " << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count() << " Milliseconds." << std::endl; | |
}; | |
// sort function caller | |
std::function< void(const std::string &&funName, templateFunctionWrapper sortFun) > SortFun = [&](const std::string &&funName, templateFunctionWrapper sortFun) { | |
beforeExecution = clockWrapper::now(); | |
standardArrayWrapper SortArray = sortFun(intArray); | |
#ifdef DEBUG_MESSAGE | |
printArray(SortArray); | |
#endif | |
afterExecution = clockWrapper::now(); | |
std::cout << funName << std::endl; | |
timeCalculate(beforeExecution, afterExecution); | |
}; | |
// print input array | |
printArray(intArray); | |
templateFunctionWrapper ptrFun; | |
// Bubble sort | |
std::thread bubbleThread(SortFun, "\nBubbleSort", ptrFun = bubbleSort<NumericType, ARRAY_SIZE>); | |
// Selection sort | |
std::thread selectionThread(SortFun, "\nSelectionSort: ", ptrFun = SelectionSort<NumericType, ARRAY_SIZE>); | |
// InsertionSort | |
std::thread insertionThread(SortFun, "\nInsertionSort:", ptrFun = InsertionSort<NumericType, ARRAY_SIZE>); | |
// Heap sort | |
std::thread heapSortThread(SortFun, "\nHeapSort: ", ptrFun = HeapSort<NumericType, ARRAY_SIZE>); | |
// Merge sort | |
std::thread mergeSortThread(SortFun, "\nMergeSort: ", ptrFun = MergeSort<NumericType, ARRAY_SIZE>); | |
bubbleThread.join(); | |
selectionThread.join(); | |
insertionThread.join(); | |
heapSortThread.join(); | |
mergeSortThread.join(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment