Skip to content
Merged
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions sorting/insertion_sort_recursive.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* @file
* @brief Insertion Sort Algorithm
*
* @details
* Insertion sort is a simple sorting algorithm that builds the final
* sorted array one element at a time. It is much less efficient compared
* to other sorting algorithms like heap sort, merge sort, or quick sort.
*
* However, it has several advantages:
* - Easy to implement.
* - Efficient for small data sets.
* - More efficient than other O(n²) algorithms like selection sort or bubble sort.
* - Stable: it does not change the relative order of elements with equal keys.
*
* Insertion sort works similarly to how people sort playing cards in their hands.
* The algorithm iterates through the list and inserts each element into its correct
* position in the sorted portion of the array.
*
* Example execution:
* 1. Start with the array [4, 3, 2, 5, 1].
* 2. Insert 3 in its correct position: [3, 4, 2, 5, 1].
* 3. Insert 2: [2, 3, 4, 5, 1].
* 4. Continue this until the array is sorted: [1, 2, 3, 4, 5].
*/

#include <algorithm> ///< for std::is_sorted
#include <cassert> ///< for assert function in testing
#include <iostream> ///< for std::cout and std::endl
#include <vector> ///< for using std::vector

/**
* @namespace sorting
* @brief Contains sorting algorithms
*/
namespace sorting {

/**
* @brief Insertion Sort Function
*
* @tparam T Type of the array elements
* @param [in,out] arr Array to be sorted
* @param n Size of the array
*/
template <typename T>
void insertionSort(T *arr, int n) {
for (int i = 1; i < n; i++) {
T temp = arr[i];
int j = i - 1;
while (j >= 0 && temp < arr[j]) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}

/**
* @brief Insertion Sort for a vector
*
* @tparam T Type of the vector elements
* @param [in,out] arr Pointer to the vector to be sorted
*/
template <typename T>
void insertionSort(std::vector<T> *arr) {
size_t n = arr->size();

for (size_t i = 1; i < n; i++) {
T temp = arr->at(i);
int32_t j = i - 1;
while (j >= 0 && temp < arr->at(j)) {
arr->at(j + 1) = arr->at(j);
j--;
}
arr->at(j + 1) = temp;
}
}

} // namespace sorting

/**
* @brief Helper function to create a random array
*
* @tparam T Type of the array elements
* @param arr Array to fill (must be pre-allocated)
* @param N Number of elements in the array
*/
template <typename T>
static void create_random_array(T *arr, int N) {
while (N--) {
double r = (std::rand() % 10000 - 5000) / 100.f;
arr[N] = static_cast<T>(r);
}
}

/**
* @brief Test Cases for the sorting algorithm
*/
void tests() {
int arr1[10] = {78, 34, 35, 6, 34, 56, 3, 56, 2, 4};
std::cout << "Test 1... ";
sorting::insertionSort(arr1, 10);
assert(std::is_sorted(arr1, arr1 + 10));
std::cout << "passed" << std::endl;

int arr2[5] = {5, -3, 7, -2, 1};
std::cout << "Test 2... ";
sorting::insertionSort(arr2, 5);
assert(std::is_sorted(arr2, arr2 + 5));
std::cout << "passed" << std::endl;

float arr3[5] = {5.6, -3.1, -3.0, -2.1, 1.8};
std::cout << "Test 3... ";
sorting::insertionSort(arr3, 5);
assert(std::is_sorted(arr3, arr3 + 5));
std::cout << "passed" << std::endl;

std::vector<float> arr4({5.6, -3.1, -3.0, -2.1, 1.8});
std::cout << "Test 4... ";
sorting::insertionSort(&arr4);
assert(std::is_sorted(std::begin(arr4), std::end(arr4)));
std::cout << "passed" << std::endl;

int arr5[50];
std::cout << "Test 5... ";
create_random_array(arr5, 50);
sorting::insertionSort(arr5, 50);
assert(std::is_sorted(arr5, arr5 + 50));
std::cout << "passed" << std::endl;

float arr6[50];
std::cout << "Test 6... ";
create_random_array(arr6, 50);
sorting::insertionSort(arr6, 50);
assert(std::is_sorted(arr6, arr6 + 50));
std::cout << "passed" << std::endl;
}

/**
* @brief Main function
*
* Empty except for the call to `tests()`.
*
* @return 0 Always returns 0.
*/
int main() {
/// Running predefined tests to test the algorithm
tests();

return 0;
}