Sorting Algorithms simulation

Play with many sorting algorithms rendered in canvas and understand how they work. Each one is accompanied with a simple c++ implementation

Bubble sort

Swaps:

template <typename T> inline void BubbleSort(
    T* arr, size_t start, size_t end,
    bool (*compare)(T a, T b) = [] (T a, T b) {return (a > b);},
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    for (size_t i = end; i > start; i--)
    {
        for (size_t j = start; j < i - 1U; j++)
        {
            if (compare(arr[j], arr[j + 1U]))
            {
                swap(&arr[j], &arr[j + 1U]);
            }
        }
    }
}

Cocktail Shaker sort

Swaps:

template <typename T> inline void ShakerSort(
    T* arr, size_t start, size_t end,
    bool (*compare)(T a, T b) = [](T a, T b) { return (a > b); },
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    size_t len = end - start;
    for (size_t p = 1U + start; p <= len / 2; p++)
    {
        for (size_t i = p - 1U; i < len - p; i++)
            if (compare(arr[i], arr[i + 1U]))
                swap(&arr[i], &arr[i + 1U]);
        for (size_t i = len - p - 1U; i >= p; i--)
            if (!compare(arr[i], arr[i - 1U]))
                swap(&arr[i], &arr[i - 1U]);
    }
}

Insertion sort

Swaps:

template <typename T> inline void InsertionSort(
    T* arr, size_t start, size_t end,
    bool (*compare)(T a, T b) = [](T a, T b) { return (a < b); },
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    for (size_t i = start + 1U; i < end; i++)
    {
        size_t j = i;
        while (j > start)
        {
            if (compare(arr[j], arr[j - 1U]))
            {
                swap(&arr[j], &arr[j - 1U]);
                j--;
            }
            else {
                j = start;
            }
        }
    }
}

Selection sort

Swaps:

template <typename T> inline void SelectionSort(
    T* arr, size_t start, size_t end,
    bool (*compare)(T a, T b) = [](T a, T b) { return (a > b); },
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    size_t min = 0;
    for (size_t i = start; i < end; i++)
    {
        min = i;
        for (size_t j = i; j < finisci; j++)
        {
            if (compare(arr[min], arr[j]))
            {
                min = j;
            }
        }
        swap(&arr[i], &arr[min]);
    }
}

Odd Even sort

Swaps:

template <typename T> inline void OddEvenSort(
    T* arr, size_t start, size_t end,
    bool (*compare)(T a, T b) = [] (T a, T b) { return (a > b); },
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    bool comapred = true;
    size_t startindex = 1U, len = end - 1U;
    while (comapred)
    {
        compared = false;
        for (size_t i = startindex + start; i < len; i += 2U)
        {
            if (compare(arr[i], arr[i + 1U]))
            {
                swap(arr[i], arr[i + 1U]);
                compared = true;
            }
        }
        startindex = 1U - startindex;
    }
}

Shell sort

Shifts

template <typename T> inline void Sort(
    T* arr, size_t since, size_t to,
	bool (*compare)(T a, T b) = [](T a, T b) {return (a > b); },
	void (*assign)(T& a, const T& b) = [](T& a, const T& b) { a = b; })
{
	for (size_t gap = (to - since) / 2U; gap > 0; gap /= 2U)
	{
		for (size_t i = gap + since; i < to; i++)
		{
			T temp = arr[i];
			size_t j = i;
			for (; j >= (gap + since) && compare(arr[j - gap], temp); j -= gap)
			{
				assign(arr[j], arr[j - gap]);
			}
			assign(arr[j], temp);
		}
	}
}

Quick sort

Swaps:

template <typename T> inline size_t QuickSortDivision(
    T* arr, size_t since, size_t to,
    bool (*compare)(T a, T b) = [](T a, T b) { return (a <= b); },
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    T pivot = arr[to];
    size_t i = since - 1U;
    for (size_t j = since; j <= (to - 1U); j++)
    {
        if (compare(arr[j], pivot))
        {
            i++;
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1U], &arr[to]);
    return (i + 1U);
}
template <typename T> inline void QuickSort(
    T* arr, size_t since, size_t to,
    bool (*compare)(T a, T b) = [](T a, T b) { return (a <= b); },
    void (*swap)(T* a, T* b) = [](T* a, T* b) { T c = *a; *a = *b; *b = c; })
{
    if (since < to)
    {
        size_t Middle_ = QuickSortDivision<T>(arr, since, to, compare, swap);
        QuickSort<T>(arr, since, Middle_ - 1U, compare, swap);
        QuickSort<T>(arr, Middle_ + 1U, to, compare, swap);
    }
}

Merge sort

Swaps:

template <typename T> void inline Merge(
	T arr[], size_t since, size_t medium, size_t to,
	bool (*compare)(T a, T b) = [](T a, T b) {return (a <= b); },
	void (*copy)(T* a, const T* b) = [](T* a, const T* b) { *a = *b; })
{
	size_t len1 = medium - since + 1U;
	size_t len2 = to - medium;
	T *L = (T*) malloc(sizeof(T)* len1), *R = (T*)malloc(sizeof(T) * len2);
	for (size_t i = 0; i < len1; i++)
		copy(L + i, arr + since + i);
	for (size_t j = 0; j < len2; j++)
		copy(R + j, arr + medium + j + 1U);
	size_t k = since, i = 0, j = 0;
	while (i < len1 && j < len2)
	{
		if (compare(L[i], R[j]))
		{
			copy(arr + k, L + i);
			i++;
		}
		else
		{
			copy(arr + k, R + j);
			j++;
		}
		k++;
	}
	for (; i < len1; i++, k++)
	{
		copy(arr + k, L + i);
	}
	free(L);
	for (; j < len2; j++, k++)
	{
		copy(arr + k, R + j);
	}
	free(R);
}
template <typename T> void inline MergeSort(
    T arr[], size_t since, size_t to,
	bool (*compare)(T a, T b) = [](T a, T b) {return (a <= b); },
	void (*copy)(T* a, const T* b) = [](T* a, const T* b) { *a = *b; })
{
	if (since < to) {
		size_t m = since + (to - since) / 2U;
		MergeSort<T>(arr, since, m, compare, copy);
		MergeSort<T>(arr, m + 1U, to, compare, copy);
		Merge<T>(arr, since, m, to, compare, copy);
	}
}