Sorting Algorithms In C++ - C++ Programming Tutorial
C++ Course / STL Algorithm / Sorting Algorithms In C++

Sorting Algorithms In C++

BLUF: Mastering Sorting Algorithms In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Sorting Algorithms In C++

C++ is renowned for its efficiency. Learn how Sorting Algorithms In C++ enables low-level control and high-performance computing in the tutorial below.

Sorting algorithms play a key role in the realm of computer science and data handling. They facilitate the organization of data components in a particular sequence, simplifying the tasks of searching, fetching, and examining data with effectiveness. Sorting stands as a crucial function across various domains, spanning from managing databases to conducting online searches, and from scientific modeling to the mechanics of video games.

The Need for Sorting Algorithms

Data commonly appears in unordered or irregularly organized formats within the digital realm. For example, search engine results are typically presented in a structured manner according to relevance following a search query. Through the utilization of sorting algorithms, individuals can promptly organize items in a catalog on an online shopping platform by their price, rating, or other attributes. Comparable to this scenario, sorting plays a vital role in ensuring efficient data retrieval when dealing with extensive datasets or databases.

Overview of Sorting Algorithms

Data items are arranged into a particular order using sorting algorithms based on predetermined criteria. They can be divided into a number of classes, each with a unique set of traits and applications. The main groups of sorting algorithms are:

  • Comparison-Based Sorting Algorithms: These algorithms compare data elements and, if necessary, exchange out of order ones. Comparison Sorts: Examples of comparison-based sorting algorithms include Bubble Sort, Insertion Sort, Selection Sort, Merge Sort, and Quick Sort. These algorithms rely on comparisons between elements to determine their relative order. Non-Comparison Sorts: Non-comparison sorting algorithms, such as Counting Sort, Radix Sort, and Bucket Sort, do not rely on element comparisons. They are often more efficient than comparison sorts in specific scenarios but have limitations.
  • Adaptive Sorting Algorithms: Based on the data's original order, adaptive sorting algorithms modify their performance. They can be quicker with partially ordered data and slower with entirely random input. Adaptive Comparison Sorts: Some comparison-based sorting algorithms, like Insertion Sort, are adaptive and perform well when given partially sorted data.
  • Stable Sorting Algorithms: The relative order of equal elements is maintained using stable sorting algorithms. In other words, even after sorting, if two elements have the same key, their positions won't change. Stable Comparison Sorts: Examples include Bubble Sort and Merge Sort.
  • In-Place Sorting Algorithms: In-place sorting algorithms do not require additional memory to sort the data. They rearrange the elements within the existing data structure. In-Place Comparison Sorts: Selection Sort and Quick Sort are in-place sorting algorithms.
  • External Sorting Algorithms: These algorithms are made to deal with data that doesn't totally fit in memory. They entail breaking the data up into smaller pieces, organizing it in memory, then combining it. External Merge Sort: A common external sorting algorithm used in database systems.
  • Parallel Sorting Algorithms: Parallel sorting algorithms leverage multiple processors or cores to sort data concurrently, reducing the time required for sorting large datasets. Parallel Merge Sort: A parallel version of Merge Sort.
  • Comparison Sorts: Examples of comparison-based sorting algorithms include Bubble Sort, Insertion Sort, Selection Sort, Merge Sort, and Quick Sort. These algorithms rely on comparisons between elements to determine their relative order.
  • Non-Comparison Sorts: Non-comparison sorting algorithms, such as Counting Sort, Radix Sort, and Bucket Sort, do not rely on element comparisons. They are often more efficient than comparison sorts in specific scenarios but have limitations.
  • Adaptive Comparison Sorts: Some comparison-based sorting algorithms, like Insertion Sort, are adaptive and perform well when given partially sorted data.
  • Stable Comparison Sorts: Examples include Bubble Sort and Merge Sort.
  • In-Place Comparison Sorts: Selection Sort and Quick Sort are in-place sorting algorithms.
  • External Merge Sort: A common external sorting algorithm used in database systems.
  • Parallel Merge Sort: A parallel version of Merge Sort.
  • Working of Sorting Algorithms

Computer science and data processing require sorting algorithms to arrange data items in a particular order. Despite the fact that there are many different sorting algorithms, they all aim to arrange data pieces in a given order, whether that be in ascending or descending order based on specified criteria.

  • Comparison or Evaluation: Sorting algorithms begin by comparing or evaluating pairs of elements in the dataset. The comparison is typically based on a specific key or attribute of each element
  • Swapping or Rearranging: When a sorting algorithm identifies that two elements are out of order, it initiates a swap operation. This operation rearranges the positions of the two elements, effectively bringing them into the correct order. The swap operation is essential for reorganizing the data elements and ensuring that they end up in the desired order.
  • Iteration or Recursion: The comparison and swapping steps are repeated iteratively or recursively until the entire dataset is sorted. The specific number of iterations or passes needed to complete the sorting process depends on the algorithm's design and the initial state of the data. Some algorithms require fewer passes than others to achieve the same result.
  • Final Result: Once all iterations or recursive calls are completed, the result is a sorted dataset. This dataset is now in the desired order, which could be in ascending or descending order based on the chosen criteria (e.g., numerical value, alphabetical order).
  • Sorting Algorithms

  • Bubble Sort: A simple comparison-based sorting algorithm. It repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order. Not efficient for large datasets but easy to understand and implement.
  • Insertion Sort: Builds the final sorted array one item at a time. It takes each element from the unsorted part and inserts it into its correct position in the sorted part. It's efficient for small datasets or partially sorted data.
  • Selection Sort: Divides the input into a sorted and an unsorted region. It repeatedly selects the minimum element from the unsorted region and moves it to the sorted region. Simple but not very efficient for large datasets.
  • Merge Sort: A divide-and-conquer algorithm that divides the unsorted list into n sub lists, each containing one element. It repeatedly merges subsists to produce new sorted sub lists until there is only one sublets remaining. Known for its stability and consistent performance.
  • Quick Sort: Another divide-and-conquer algorithm. It selects a 'pivot' element from the array and partitions the other elements into two sub-arrays according to whether they are less than or greater than the pivot. Efficient for large datasets and often used in practice.
  • Heap Sort: Builds a binary heap from the data and repeatedly removes the largest (for max heap) or smallest (for min heap) element. Efficient and has a time complexity of O(n log n) but not a stable sorting algorithm.
  • Radix Sort: Sorts numbers by processing individual digits. It can be used for integers or strings, where each digit or character is considered at a time. Can be very efficient for certain types of data.
  • Counting Sort: Suitable for sorting integers within a specified range. It counts the frequency of each element and uses this information to place elements in sorted order. Fast and stable but not suitable for datasets with a wide range of values.
  • Bucket Sort: Divides the data into a finite number of buckets, each of which is then sorted individually. Suitable for distributed data and can be very efficient when the data is uniformly distributed.
  • Shell Sort: An extension of insertion sort where elements at a specified interval are compared and swapped. The interval decreases with each pass until the whole array is sorted. Offers a balance between insertion sort and quick sort in terms of efficiency.
  • A simple comparison-based sorting algorithm.
  • It repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong order.
  • Not efficient for large datasets but easy to understand and implement.
  • Builds the final sorted array one item at a time.
  • It takes each element from the unsorted part and inserts it into its correct position in the sorted part.
  • It's efficient for small datasets or partially sorted data.
  • Divides the input into a sorted and an unsorted region.
  • It repeatedly selects the minimum element from the unsorted region and moves it to the sorted region.
  • Simple but not very efficient for large datasets.
  • A divide-and-conquer algorithm that divides the unsorted list into n sub lists, each containing one element.
  • It repeatedly merges subsists to produce new sorted sub lists until there is only one sublets remaining.
  • Known for its stability and consistent performance.
  • Another divide-and-conquer algorithm.
  • It selects a 'pivot' element from the array and partitions the other elements into two sub-arrays according to whether they are less than or greater than the pivot.
  • Efficient for large datasets and often used in practice.
  • Builds a binary heap from the data and repeatedly removes the largest (for max heap) or smallest (for min heap) element.
  • Efficient and has a time complexity of O(n log n) but not a stable sorting algorithm.
  • Sorts numbers by processing individual digits.
  • It can be used for integers or strings, where each digit or character is considered at a time.
  • Can be very efficient for certain types of data.
  • Suitable for sorting integers within a specified range.
  • It counts the frequency of each element and uses this information to place elements in sorted order.
  • Fast and stable but not suitable for datasets with a wide range of values.
  • Divides the data into a finite number of buckets, each of which is then sorted individually.
  • Suitable for distributed data and can be very efficient when the data is uniformly distributed.
  • An extension of insertion sort where elements at a specified interval are compared and swapped.
  • The interval decreases with each pass until the whole array is sorted.
  • Offers a balance between insertion sort and quick sort in terms of efficiency.
  • Bubble Sort Algorithm in C++

  • Go down the list starting at the top.
  • Assess the first two elements. Exchange the first and second elements if the first element is bigger than the second element.
  • Repeat steps 2 and 3 for the subsequent group of components to cycle over the list of elements.
  • Repeat steps 2 and 3 until the list is complete.
  • The largest unsorted entry will have "bubbled up" to the end of the list after being traversed once.
  • Repetition of steps 1 through 5 will sort the remaining unsorted elements of the list (apart from the final item, which is already in the proper position).
  • Repeat these steps for each element until no more swaps are required and all the elements pass the merge sort condition, at which point the list will be considered sorted.

Source Code

Example

// Function to perform Bubble Sort on an array
void bubbleSort(int arr[], int n) {
    bool swapped;
    for (int i = 0; i < n - 1; i++) {
        swapped = false;
        for (int j = 0; j < n - i - 1; j++) {

int next = arr[j+1];
            if (arr[j] > next) {
                int temp = arr[j];
                arr[j] = next];
                next = temp;
                swapped = true; // Mark that a swap occurred
            }
        }
        // If no two elements were swapped in inner loop, the array is already sorted
        if (!swapped) {
            break;
        }
    }
}
int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int len = sizeof(arr)
    int n = len / len[0];
    // Call Bubble Sort to sort the array
    bubbleSort(arr, n);
    return 0;
}

Merge Sort in C++

  • Divide the unsorted array into two halves by finding the middle point.
  • Recursively sort the left half and the right half.
  • Merge the sorted halves back together to produce a single sorted array.

The crucial stage in the Merge Sort algorithm is the merging step, where two pre-sorted arrays are merged into a single sorted array. During this process, elements from each array are compared and arranged in ascending order within a temporary array.

Source Code

Example

void merge(std::vector<int>& arr, int l, int m, int r) {
    int n1 = m - l + 1;
    int n2 = r - m;
    // Create temporary arrays
    std::vector<int> L(n1);
    std::vector<int> R(n2);
    // Copy data to temporary arrays L[] and R[]
    for (int i = 0; i < n1; i++) {
        L[i] = arr[l + i];
    }
    for (int i = 0; i < n2; i++) {
        R[i] = arr[m + 1 + i];
    }
    // Merge the temporary arrays back into arr[l..r]
    int i = 0; // Initial index of first subarray
    int j = 0; // Initial index of second subarray
    int k = l; // Initial index of merged subarray
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }
    // Copy the remaining elements of L[], if there are any
    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }
    // Copy the remaining elements of R[], if there are any
    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}
// Main Merge Sort function
void mergeSort(std::vector<int>& arr, int l, int r) {
    if (l < r) {
        // Find the middle point
        int m = l + (r - l) / 2;
        // Sort the first and second halves
        mergeSort(arr, l, m);
        mergeSort(arr, m + 1, r);
        // Merge the sorted halves
        merge(arr, l, m, r);
    }
}
int main() {
    mergeSort(arr, 0, n - 1);
    return 0;
}

Insertion Sort

The simple sorting method called insertion sort arranges the sorted array gradually, one element at a time. While it may not be as efficient as advanced algorithms like quicksort, heapsort, or merge sort, especially for large datasets, it still offers advantages. For small datasets or partially sorted lists, insertion sort is a fast and convenient option.

Source Code

Example

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        // Move elements of arr[0..i-1] that are greater than key
        // to one position ahead of their current position
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}
int main() {
    insertionSort(arr, n);
    return 0;
}

Selection Sort

A straightforward sorting technique called selection sort repeatedly places the least (or highest, depending on the sorting order) element from the array's unsorted portion at the start of the portion that has been sorted. Its time complexity is O(n2), making it unsuitable for huge datasets, although it can be helpful for tiny lists or as a component of more sophisticated sorting algorithms.

  • Find the minimum (or maximum) element from the unsorted portion of the array.
  • Swap the minimum (or maximum) element with the first element of the unsorted portion.
  • Move the boundary between the sorted and unsorted portions one element to the right.
  • Repeat steps 1-3 until the entire array is sorted.
Example

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        // Swap the found minimum element with the first element
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}
int main() {
    selectionSort(arr, n);
    return 0;
}

Quick Sort

Quick sort is a comparison-based, divide-and-conquer sorting algorithm. Choosing one element from the array to act as the "pivot" element and dividing the remaining items into two sub-arrays based on whether they are less than or greater than the pivot element is how it operates. The sub-arrays are next sorted recursively. The array gets sorted completely once this operation is finished. One of the quickest sorting algorithms, quick sort has an average and best-case time complexity of O(n log n). In the worst scenario, it can, nevertheless, become O(n2).

  • Pick one pivotal component from the array.
  • Partitioning: Rearrange the array so that all elements that are smaller than the pivot go in front of it and all elements that are larger than the pivot go in back. The pivot is now in the place it was sorted to.
  • Recursively use Quick Sort on the sub-arrays on the left (which contain elements below the pivot) and the right (which contain entries above the pivot).
  • Keep doing this until the full array has been sorted.

Source Code

Example

int partition(int arr[], int low, int high) {
    int pivot = arr[high]; // Choose the pivot as the last element
    int i = (low - 1);     // Index of the smaller element
    for (int j = low; j <= high - 1; j++) {
        if (arr[j] <= pivot) {
            i++; // Increment index of the smaller element
            std::swap(arr[i], arr[j]);
        }
    }
    std::swap(arr[i + 1], arr[high]);
    return (i + 1); // Return the index of the pivot element
}
// Function to implement Quick Sort
void quickSort(int arr[], int low, int high) {
    if (low < high) {
        // Partition the array into two sub-arrays and get the pivot index
        int pivotIndex = partition(arr, low, high);
        // Recursively sort the sub-arrays
        quickSort(arr, low, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, high);
    }
}
int main() {
    quickSort(arr, 0, n - 1);
    return 0;
}

Heap Sort

The binary heap data structure's advantages are used by the comparison-based heap sort method. It repeatedly removes the maximum (for max-heap) or minimum (for min-heap) element from the unsorted region and adds it to the sorted region after dividing the input array into a sorted and an unsorted region. The array gets sorted completely once this operation is finished. Heap sort is an in-place sorting algorithm with an O(n log n) time complexity.

  • Start by using the input array to generate a binary heap. Each entry at index i has two progenies at positions 2i + 1 and 2i + 2, respectively, in a binary heap that is often represented as an array. The binary heap can be either a max-heap or a min-heap depending on whether you want to sort in ascending or descending order.
  • The element with the highest or lowest value in the unsorted region is found at the root of a max-heap or min-heap, respectively. The last element in the area that isn't sorted should be used in place of this element.
  • Decrease the size of the heap (exclude the last element) and restore the heap property (heapify the root).
  • Repeat steps 2 and 3 until the heap is empty. The sorted elements will accumulate at the end of the array, in descending order for max-heap or ascending order for min-heap.

Source Code

Example

#include <iostream>
// Function to heapify a subtree rooted at index i in a max-heap
void heapify(int arr[], int n, int i) {
    int largest = i;    // Initialize largest as the root
    int left = 2 * i + 1; // Left child
    int right = 2 * i + 2; // Right child
    // If the left child is larger than the root
    if (left < n && arr[left] > arr[largest]) {
        largest = left;
    }
    // If the right child is larger than the largest so far
    if (right < n && arr[right] > arr[largest]) {
        largest = right;
    }
    // If the largest element is not the root, swap and heapify the affected subtree
    if (largest != i) {
        std::swap(arr[i], arr[largest]);
        heapify(arr, n, largest);
    }
}
// Main function to perform heap sort
void heapSort(int arr[], int n) {
    // Build a max-heap from the input array
    for (int i = n / 2 - 1; i >= 0; i--) {
        heapify(arr, n, i);
    }
    // Extract elements one by one from the heap
    for (int i = n - 1; i > 0; i--) {
        std::swap(arr[0], arr[i]);
        // Call heapify on the reduced heap
        heapify(arr, i, 0);
    }
}
main() 
{
    heapSort(arr, n);
    return 0;
}

Radix Sort

A non-comparative sorting method called radix sort divides objects into buckets based on the specific digits or characters they contain. From least significant (rightmost) to most significant (leftmost), the digits or characters are processed. At each pass, the elements are rearranged into buckets according on the current digit's value. A sorted array is created by concatenating the components back in the order they were placed in the buckets after processing all of the numbers.

  • To ascertain the number of digits, find the largest number in the array.
  • From the least significant digit to the most significant digit for each digit position:
  • Initialize the empty buckets (0-9 for integers with base 10).
  • Based on the current digit, put each element in the appropriate bucket.
  • Combine the buckets to create a new array that is sorted.
  • For each position of the digit, repeat step 2.
  • Now the array has been sorted.
  • C++ code

Example

// Function to find the maximum element in an array
int findMax(std::vector<int>& arr) {
    int max = arr[0];
int len = arr.size();
    for (int i = 1; i < len; ++i) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}
// Function to perform Radix Sort on an array of integers
void radixSort(std::vector<int>& arr) {
    int max = findMax(arr);
    int exp = 1; // Initialize the digit position (1s, 10s, 100s, etc.)
    while (max / exp > 0) {
        std::vector<int> output(arr.size(), 0); // Initialize an output array
        std::vector<int> count(10, 0); // Initialize counting array for digits 0-9
        // Count the occurrences of each digit at the current position
        for (int i = 0; i < len; ++i) {
            count[(arr[i] / exp) % 10]++;
        }
        // Update the count array to store the cumulative counts
        for (int i = 1; i < 10; ++i) {
            count[i] += count[i - 1];
        }
        // Build the output array by placing elements in the correct positions
        for (int i = len - 1; i >= 0; --i) {
            output[count[(arr[i] / exp) % 10] - 1] = arr[i];
            count[(arr[i] / exp) % 10]--;
        }
        for (int i = 0; i < len; ++i) {
            arr[i] = output[i];
        }
        exp *= 10;
    }
}
main() 
{
    radixSort(arr);
    return 0;
}

Counting Sort

Counting For sorting objects or numbers with a narrow range of values, sort is an effective, non-comparative sorting method. In order to put the elements in the proper sorted order, it counts the frequency of each unique element in the input data.

  • Find the min value and max value of the input array.
  • Create a counting array to store the count of each unique element in the range.
  • Traverse the input array and increment the count for each element.
  • Calculate the cumulative sum of counts in the counting array. This step helps determine the correct position for each element in the sorted output.
  • Initialize an output array to store the sorted elements.
  • Traverse the input array in reverse order (to maintain stability) and place each element in its correct position in the output array based on the cumulative count.
  • The output array now contains the sorted elements.
  • C++ code

Example

#include <vector>
void countingSort(std::vector<int>& arr) {
    int n = arr.size();
    // Find the minimum and maximum values in the input array
    int minVal = arr[0];
    int maxVal = arr[0];
    for (int i = 1; i < n; ++i) {
        if (arr[i] < minVal) minVal = arr[i];
        if (arr[i] > maxVal) maxVal = arr[i];
    }
    // Create a counting array to store element frequencies
    int range = maxVal - minVal + 1;
    std::vector<int> count(range, 0);
    // Count the occurrences of each element
    for (int i = 0; i < n; ++i) {
        count[arr[i] - minVal]++;
    }
    // Calculate cumulative counts
    for (int i = 1; i < range; ++i) {
        count[i] += count[i - 1];
    }
    // Create the output array
    std::vector<int> output(n);
    // Place elements in the correct positions in the output array
    for (int i = n - 1; i >= 0; --i) {
        output[count[arr[i] - minVal] - 1] = arr[i];
        count[arr[i] - minVal]--;
    }
    // Copy the sorted elements back to the input array
    for (int i = 0; i < n; ++i) {
        arr[i] = output[i];
    }
}
int main() {
    countingSort(arr);
    return 0;
}

Bucket Sort

Bucket sort is a sorting algorithm that works by dividing the input into a fixed number of equally spaced "buckets," distributing the elements into these buckets, and then sorting each bucket individually, typically using another sorting algorithm like insertion sort or quicksort. You concatenate all the sorted buckets after sorting each one to get the final sorted array.

  • Decide on the program's bucket count and the range of input values that will be accepted.
  • Create a set of empty buckets in an array to represent each value in the range.
  • Iterate through the input array, assigning each entry to the appropriate bucket using a mapping function. Using the mapping function, values should be spread equally among the buckets.
  • Sort each bucket individually, either using another sorting algorithm or recursively applying the bucket sort algorithm if the bucket size is large enough.
  • Concatenate all the sorted buckets to obtain the final sorted array.

Source Code

Example

// Function to perform bucket sort
void bucketSort(vector<float>& arr) {
    int n = arr.size();
    // Create empty buckets
    vector<vector<float>> buckets(n);
    // Place elements into buckets
    for (int i = 0; i < n; i++) {
        int bucket_index = n * arr[i];
        buckets[bucket_index].push_back(arr[i]);
    }
    // Sort each bucket (using another sorting algorithm)
    for (int i = 0; i < n; i++) {
        sort(buckets[i].begin(), buckets[i].end());
    }
    // Concatenate sorted buckets to obtain the final sorted array
    int index = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < buckets[i].size(); j++) {
            arr[index++] = buckets[i][j];
        }
    }
}
main() 
{
    vector<float> arr = {0.42, 0.32, 0.33, 0.52, 0.37, 0.47, 0.51};
    bucketSort(arr);
    return 0;
}

Shell Sort

Shell Sort is an efficient, in-place, and unstable sorting algorithm that's an extension of the Insertion Sort algorithm. It works by repeatedly sorting elements that are distant from each other, gradually reducing the gap between elements to be compared until it becomes 1. At this point, the algorithm becomes equivalent to a simple Insertion Sort, but due to the prior sorting passes, the array is partially sorted, which can significantly improve the Insertion Sort's performance.

  • Choose a sequence of gap values (often referred to as the "increment sequence") that starts with a relatively large gap and progressively reduces it. Common sequences include the Knuth sequence (3k+1) or simply dividing the gap by 2 in each pass.
  • Starting with the largest gap, repeatedly perform Insertion Sort on subarrays of the original array, where the elements in each subarray are separated by the chosen gap value.
  • Decrease the gap gradually and repeat step 2 until the gap becomes equal to 1, which is equivalent to a final Insertion Sort pass on the entire array.

Source Code

Example

// Function to perform Shell Sort on a vector
void shellSort(vector<int>& arr) {
    int n = arr.size();
    // Start with a large gap and reduce it over multiple passes
    for (int gap = n / 2; gap > 0; gap /= 2) {
        // Perform Insertion Sort on subarrays with a specific gap
        for (int i = gap; i < n; i++) {
            int temp = arr[i];
            int j;
            // Shift elements in the subarray until the correct position is found
            for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
                arr[j] = arr[j - gap];
            }
            // Place the current element in its correct position
            arr[j] = temp;
        }
    }
}
 main() 
{
    vector<int> arr = {12, 34, 54, 2, 3};
    shellSort(arr);
    return 0;
}

Application of Sorting Algorithms

  • Data Retrieval: Sorting algorithms are used to efficiently retrieve data from databases and file systems. For example, databases often use sorting to quickly locate records with specific criteria.
  • Search Algorithms: Many search algorithms, such as binary search, call for the sorting of data prior to the search. Finding a specific item in a list fast is made possible by sorting.
  • Arranging Results: Search results that are requested by the end-user, items, or postings are arranged using sorting algorithms in software applications like search engines like Google, e-commerce websites, and social media platforms based on relevance, user preferences, or other factors like whether the products are sponsored.
  • Data Analysis: Data and statistics can be sorted to look for patterns, outliers, and trends. Data can exhibit temporal trends by being grouped according to time, for instance.
  • File and Directory Listing: File systems use sorting algorithms to display files and directories in an ordered manner, making it easier for users to find and manage their files.
  • Task Scheduling: Scheduling algorithms often require sorting tasks or processes based on priority, deadline, or other criteria.
  • Optimization Problems: Some optimization problems involve sorting as an intermediate step. For example, the traveling salesman problem can benefit from sorting cities based on their proximity.
  • Graph Algorithms: In graph algorithms like Kruskal's algorithm for minimum spanning trees, sorting edges based on their weights is a critical step.
  • Image Processing: Image processing applications may use sorting to order pixels based on intensity, color, or other attributes.
  • Natural Language Processing (NLP): In NLP, sorting may be used to order documents or sentences by relevance or other criteria.
  • Genetics: Genetic algorithms may involve sorting individuals in a population based on fitness or other genetic characteristics.
  • Computer Graphics: Rendering and animation applications sometimes use sorting to determine the order in which objects are drawn, taking into account their depth or transparency.
  • Load Balancing: In distributed systems and cloud computing, load balancing algorithms may sort tasks or data to distribute the load evenly among resources.
  • Routing and Navigation: In GPS and map applications, sorting algorithms may be used to order waypoints or routes based on distance or time.
  • Collaborative Filtering: Recommender systems often use sorting to rank and recommend items to users based on their preferences and behavior.
  • Financial and Stock Market Analysis: In order to find trends and make investment decisions, financial data, such as stock prices, are sorted using algorithms.
  • Games and simulations can utilize sorting to arrange objects, characters, or events according to numerous criteria, such as proximity, rapidity, or significance.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience