Add example for cpp/algorithms/sorting/merge

This commit is contained in:
Shaun Reed 2021-05-24 12:11:33 -04:00
parent fa4407e74a
commit b2bdd62fb2
5 changed files with 138 additions and 0 deletions

View File

@ -14,4 +14,5 @@ project (
DESCRIPTION "A project for practicing various algorithms in C++" DESCRIPTION "A project for practicing various algorithms in C++"
LANGUAGES CXX LANGUAGES CXX
) )
add_subdirectory(sorting) add_subdirectory(sorting)

View File

@ -8,5 +8,12 @@
# #
cmake_minimum_required(VERSION 3.15) 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) add_subdirectory(selection)

View File

@ -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 <algorithm>
#include <iostream>
#include <vector>
void MergeSort(std::vector<int> &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<int> &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<int> lhsArray(lhsLength + 1);
std::vector<int> 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++];
}
}
}

View File

@ -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 <vector>
void MergeSort(std::vector<int> &array, size_t lhs, size_t rhs);
void Merge(std::vector<int> &array, size_t lhs, size_t mid, size_t rhs);
#endif // LIB_MERGE_H

View File

@ -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 <algorithm>
#include <iostream>
#include <vector>
int main(int const argc, char const * argv[]) {
std::srand(time(nullptr));
std::vector<int> array(ARRAY_LENGTH, 0);
std::generate(array.begin(), array.end(), [](){ return rand() % 1000;});
auto print = [](const std::vector<int> &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;
}