diff --git a/cpp/algorithms/CMakeLists.txt b/cpp/algorithms/CMakeLists.txt index 1614365..5f9d0aa 100644 --- a/cpp/algorithms/CMakeLists.txt +++ b/cpp/algorithms/CMakeLists.txt @@ -14,4 +14,5 @@ project ( DESCRIPTION "A project for practicing various algorithms in C++" LANGUAGES CXX ) + add_subdirectory(sorting) diff --git a/cpp/algorithms/sorting/CMakeLists.txt b/cpp/algorithms/sorting/CMakeLists.txt index c921db0..ac988d6 100644 --- a/cpp/algorithms/sorting/CMakeLists.txt +++ b/cpp/algorithms/sorting/CMakeLists.txt @@ -8,5 +8,12 @@ # cmake_minimum_required(VERSION 3.15) +project ( + #[[NAME]] Sorting-Algorithms + VERSION 1.0 + DESCRIPTION "A project for practicing various sorting algorithms in C++" + LANGUAGES CXX +) +add_subdirectory(merge) add_subdirectory(selection) diff --git a/cpp/algorithms/sorting/merge/lib-merge.cpp b/cpp/algorithms/sorting/merge/lib-merge.cpp new file mode 100644 index 0000000..2d43e2c --- /dev/null +++ b/cpp/algorithms/sorting/merge/lib-merge.cpp @@ -0,0 +1,74 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of merge sort using a custom library ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#include "lib-merge.h" + +#include +#include +#include + +void MergeSort(std::vector &array, size_t lhs, size_t rhs) +{ + // Base case to break recursion; When we are left with < 2 values + // + Since we cannot split a single value into two arrays without duplicating + if (lhs >= rhs) { + return; // Insert breakpoint here and walk up call stack for more info + } + // We will never have a negative result from (l + r) + // + Truncation to zero will floor division by 2 + size_t mid = (lhs + rhs) / 2; + + // Recurse into lhsArray[lhs ... mid]; Repeat until we hit base case + // + Next call will recurse into a smaller lhsArray + MergeSort(array, lhs, mid); + // Recurse into rhsArray[mid + 1 ... rhs]; Repeat until we hit base case + MergeSort(array, mid + 1, rhs); + // Merge is called after we reach the first base case + Merge(array, lhs, mid, rhs); +} + +void Merge(std::vector &array, size_t lhs, size_t mid, size_t rhs) +{ + size_t lhsLength = mid - lhs + 1; + size_t rhsLength = rhs - mid; + + // Create lhsArray, rhsArray with one additional index for a sentinel value + std::vector lhsArray(lhsLength + 1); + std::vector rhsArray(rhsLength + 1); + + // Initialize lhsArray from array[0] to array[mid] + for (size_t i = 0; i < lhsLength; i++) lhsArray[i] = array[lhs + i]; + // Initialize rhsArray from array[mid + 1] to array[rhs] + for (size_t j = 0; j < rhsLength; j++) rhsArray[j] = array[mid + 1 + j]; + + // Set the sentinel values for final index of lhsArray, rhsArray + // + When we hit these values during a merge, they are always greater than + // ++ Set to the maximum possible value; There can never be anything larger + lhsArray[lhsLength] = INT32_MAX; + rhsArray[rhsLength] = INT32_MAX; + + // Start at the beginning of both subarrays + // + i + size_t lhsIndex = 0; + size_t rhsIndex = lhsIndex; // Starting at 0, same as lhsIndex + + // For each value across both subarrays; From lhs to rhs + // + Check all values across lhsArray[lhs... mid] and rhsArray[mid + 1.. rhs] + // ++ When mergeIndex hits the value of rhs, we are done scanning both arrays + for (size_t mergeIndex = lhs; mergeIndex <= rhs; mergeIndex++) { + // If either value is a sentinel, the non-sentinel value is always less than + if (lhsArray[lhsIndex] <= rhsArray[rhsIndex]) { + array[mergeIndex] = lhsArray[lhsIndex++]; + } + else { // rhsArray[rhsIndex] < lhsArray[lhsIndex] + array[mergeIndex] = rhsArray[rhsIndex++]; + } + } + +} diff --git a/cpp/algorithms/sorting/merge/lib-merge.h b/cpp/algorithms/sorting/merge/lib-merge.h new file mode 100644 index 0000000..5e5c31d --- /dev/null +++ b/cpp/algorithms/sorting/merge/lib-merge.h @@ -0,0 +1,21 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of merge sort using a custom library ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#ifndef LIB_MERGE_H +#define LIB_MERGE_H + +#define ARRAY_LENGTH 10 + +#include + +void MergeSort(std::vector &array, size_t lhs, size_t rhs); + +void Merge(std::vector &array, size_t lhs, size_t mid, size_t rhs); + +#endif // LIB_MERGE_H diff --git a/cpp/algorithms/sorting/merge/merge-sort.cpp b/cpp/algorithms/sorting/merge/merge-sort.cpp new file mode 100644 index 0000000..ad75338 --- /dev/null +++ b/cpp/algorithms/sorting/merge/merge-sort.cpp @@ -0,0 +1,35 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of merge sort using a custom library ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#include "lib-merge.h" + +#include +#include +#include + +int main(int const argc, char const * argv[]) { + std::srand(time(nullptr)); + std::vector array(ARRAY_LENGTH, 0); + std::generate(array.begin(), array.end(), [](){ return rand() % 1000;}); + + auto print = [](const std::vector &array) { + for (const auto &value : array) std::cout << value << ", "; + std::cout << std::endl; + }; + + std::cout << "Unsorted array:\n"; + print(array); + + MergeSort(array, 0, array.size() - 1); + + std::cout << "Sorted array:\n"; + print(array); + + return 0; +}