From c8d86326132b2771ed969882c4abd52e9fcc90d5 Mon Sep 17 00:00:00 2001 From: Khushboo Shakya <72929479+khushbooshakya@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:56:25 +0530 Subject: [PATCH] Update binary_insertion_sort.cpp Improved Commenting Explanation: General Overview: Detailed explanation of each function and its purpose. Clearly indicates what each parameter is and how the function works. Algorithm Details: The purpose of binary search and how it helps improve the performance of insertion sort is explained. Describes how each element is inserted in the correct place by shifting larger elements to the right. Test Function: Comments explain what each test case is doing, what type of data is being sorted, and how the program verifies if the sorting is successful. This should help anyone reading the code to understand not only how the code works but also why each part is necessary. --- sorting/binary_insertion_sort.cpp | 161 ++++++++++++++---------------- 1 file changed, 73 insertions(+), 88 deletions(-) diff --git a/sorting/binary_insertion_sort.cpp b/sorting/binary_insertion_sort.cpp index f0404c6b45a..1d2ae183fae 100644 --- a/sorting/binary_insertion_sort.cpp +++ b/sorting/binary_insertion_sort.cpp @@ -1,146 +1,131 @@ -/** - * \file - * \brief [Binary Insertion Sort Algorithm - * (Insertion Sort)](https://en.wikipedia.org/wiki/Insertion_sort) - * - * \details - * If the cost of comparisons exceeds the cost of swaps, as is the case for - * example with string keys stored by reference or with human interaction (such - * as choosing one of a pair displayed side-by-side), then using binary - * insertion sort may yield better performance. Binary insertion sort employs a - * binary search to determine the correct location to insert new elements, and - * therefore performs ⌈log2 n⌉ comparisons in the worst case. When each element - * in the array is searched for and inserted this is O(n log n). The algorithm - * as a whole still has a running time of O(n2) on average because of the series - * * of swaps required for each insertion. However it has several advantages - * such as - * 1. Easy to implement - * 2. For small set of data it is quite efficient - * 3. More efficient that other Quadratic complexity algorithms like - * Selection sort or bubble sort. - * 4. It is efficient to use it when the cost of comparison is high. - * 5. It's stable that is it does not change the relative order of - * elements with equal keys. - * 6. It can sort the array or list as it receives. - * - * Example execution steps: - * 1. Suppose initially we have - * \f{bmatrix}{40 &30 &20 &50 &10\f} - * 2. We start traversing from 40 till we reach 10 - * when we reach at 30 we find that it is not at it's correct place so we take - * 30 and place it at a correct position thus the array will become - * \f{bmatrix}{30 &40 &20 &50 &10\f} - * 3. In the next iteration we are at 20 we find that this is also misplaced so - * we place it at the correct sorted position thus the array in this iteration - * becomes - * \f{bmatrix}{20 &30 &40 &50 &10\f} - * 4. We do not do anything with 50 and move on to the next iteration and - * select 10 which is misplaced and place it at correct position. Thus, we have - * \f{bmatrix}{10 &20 &30 &40 &50\f} - */ - -#include /// for algorithm functions -#include /// for assert -#include /// for IO operations -#include /// for working with vectors +#include /// for algorithm functions like std::is_sorted +#include /// for assert to check if the sorting is correct +#include /// for input-output operations +#include /// for using std::vector to store and sort the elements /** * \namespace sorting - * @brief Sorting algorithms + * @brief Contains sorting algorithms + * + * This namespace groups all the sorting-related algorithms together. */ namespace sorting { /** - * \brief Binary search function to find the most suitable pace for an element. - * \tparam T The generic data type. - * \param arr The actual vector in which we are searching a suitable place for - * the element. \param val The value for which suitable place is to be found. - * \param low The lower bound of the range we are searching in. - * \param high The upper bound of the range we are searching in. - * \returns the index of most suitable position of val. + * \brief Binary search function to find the correct position for an element. + * + * This function uses binary search to determine the most suitable position for + * inserting a new element into an already sorted portion of the array. + * + * \tparam T The type of elements in the array (e.g., int, float, etc.). + * \param arr The array (vector) in which we are searching for the position to insert the element. + * \param val The value to be inserted in the sorted part of the array. + * \param low The lower bound (starting index) of the array range we are searching in. + * \param high The upper bound (ending index) of the array range we are searching in. + * \returns The index where the value `val` should be inserted. */ template int64_t binary_search(std::vector &arr, T val, int64_t low, int64_t high) { + // If the range contains only one element, return the appropriate position if (high <= low) { + // If the value to insert is greater than the element at 'low', return 'low + 1', otherwise 'low' return (val > arr[low]) ? (low + 1) : low; } + + // Calculate the middle index of the current range int64_t mid = low + (high - low) / 2; + + // If the value is less than the middle element, search in the left half if (arr[mid] > val) { return binary_search(arr, val, low, mid - 1); - } else if (arr[mid] < val) { + } + // If the value is greater than the middle element, search in the right half + else if (arr[mid] < val) { return binary_search(arr, val, mid + 1, high); - } else { + } + // If the value is equal to the middle element, insert it just after 'mid' + else { return mid + 1; } } /** - * \brief Insertion sort function to sort the vector. - * \tparam T The generic data type. - * \param arr The actual vector to sort. - * \returns Void. + * \brief Binary Insertion Sort function that sorts the array using binary search for insertion. + * + * This function sorts the array by finding the appropriate position for each element using + * binary search and inserting it into the sorted part of the array. It reduces the number of + * comparisons compared to linear insertion sort, but the number of shifts (swaps) remains the same. + * + * \tparam T The type of elements in the array (e.g., int, float, etc.). + * \param arr The array (vector) to be sorted. */ template void insertionSort_binsrch(std::vector &arr) { - int64_t n = arr.size(); + int64_t n = arr.size(); // Get the size of the array + // Traverse the array from the second element to the last for (int64_t i = 1; i < n; i++) { - T key = arr[i]; - int64_t j = i - 1; + T key = arr[i]; // The current element to be inserted + int64_t j = i - 1; // The last index of the sorted part of the array + + // Find the location to insert the current element using binary search int64_t loc = sorting::binary_search(arr, key, 0, j); + + // Shift elements that are greater than 'key' to one position ahead while (j >= loc) { - arr[j + 1] = arr[j]; + arr[j + 1] = arr[j]; // Move element to the right j--; } - arr[j + 1] = key; + arr[j + 1] = key; // Insert the key at the correct position } } } // namespace sorting /** - * @brief Self-test implementations - * @returns void + * @brief Function to test the Binary Insertion Sort algorithm with different test cases. + * + * This function tests the sorting algorithm using different sets of data + * and asserts that the array is sorted correctly after the sort operation. */ static void test() { - /* descriptions of the following test */ - /* 1st test: - [5, -3, -1, -2, 7] returns [-3, -2, -1, 5, 7] */ + // Test case 1: Sorting integers std::vector arr1({5, -3, -1, -2, 7}); std::cout << "1st test... "; - sorting::insertionSort_binsrch(arr1); - assert(std::is_sorted(std::begin(arr1), std::end(arr1))); - std::cout << "passed" << std::endl; + sorting::insertionSort_binsrch(arr1); // Sort the array + assert(std::is_sorted(arr1.begin(), arr1.end())); // Check if the array is sorted + std::cout << "passed" << std::endl; // Output result if test passed - /* 2nd test: - [12, 26, 15, 91, 32, 54, 41] returns [12, 15, 26, 32, 41, 54, 91] */ + // Test case 2: Sorting a larger set of integers std::vector arr2({12, 26, 15, 91, 32, 54, 41}); std::cout << "2nd test... "; - sorting::insertionSort_binsrch(arr2); - assert(std::is_sorted(std::begin(arr2), std::end(arr2))); + sorting::insertionSort_binsrch(arr2); // Sort the array + assert(std::is_sorted(arr2.begin(), arr2.end())); // Check if the array is sorted std::cout << "passed" << std::endl; - /* 3rd test: - [7.1, -2.5, -4.0, -2.1, 5.7] returns [-4.0, -2.5, -2.1, 5.7, 7.1] */ + // Test case 3: Sorting floating-point numbers std::vector arr3({7.1, -2.5, -4.0, -2.1, 5.7}); std::cout << "3rd test... "; - sorting::insertionSort_binsrch(arr3); - assert(std::is_sorted(std::begin(arr3), std::end(arr3))); + sorting::insertionSort_binsrch(arr3); // Sort the array + assert(std::is_sorted(arr3.begin(), arr3.end())); // Check if the array is sorted std::cout << "passed" << std::endl; - /* 4th test: - [12.8, -3.7, -20.7, -7.1, 2.2] returns [-20.7, -7.1, -3.7, 2.2, 12.8] */ + // Test case 4: Sorting another set of floating-point numbers std::vector arr4({12.8, -3.7, -20.7, -7.1, 2.2}); std::cout << "4th test... "; - sorting::insertionSort_binsrch(arr4); - assert(std::is_sorted(std::begin(arr4), std::end(arr4))); + sorting::insertionSort_binsrch(arr4); // Sort the array + assert(std::is_sorted(arr4.begin(), arr4.end())); // Check if the array is sorted std::cout << "passed" << std::endl; } /** - * @brief Main function - * @return 0 on exit. + * @brief Main function. + * + * This is the entry point of the program. It runs the test function to verify + * the correctness of the Binary Insertion Sort algorithm. + * + * @return 0 on successful execution. */ int main() { - test(); // run self-test implementations - return 0; + test(); // Run the test cases + return 0; // Exit the program }