Skip to content

Instantly share code, notes, and snippets.

@shajeen
Created August 2, 2019 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shajeen/7b40cdb0006e0cb4c344c4aa2ce78bc6 to your computer and use it in GitHub Desktop.
Save shajeen/7b40cdb0006e0cb4c344c4aa2ce78bc6 to your computer and use it in GitHub Desktop.
c++11 standard sorting algorithm implementation
// 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