Recursive Divide--Example 4. Quick sorting

Recursive Dividing - Example 4. Quick Sorting

1. Description of the problem

Given an array, use the quick sort algorithm to sort.

2. Solving problems

Familiar QuickRow, written several times before. RandomizedQuickSort, an algorithm for random pivot selection, is also extended here.
The idea of Quick Row is simple:
For input a[p:r], sort by three steps:

  • Decomposition: Take one element in a as pivot to divide a[p:r] into three segments: a[p:q-1], a[q], a[q+1:r], so that any element in a[p:q-1]<=a[q], and any element in a[q+1:r]>=a[q]; Subscript q is determined in the partitioning process.
  • Recursive Solution: Recursively invoke Quick Sort to sort a[p: q-1] and a[q+1: r] respectively.
  • Merge: merge a[p:q-1], a[q], a[q+1:r] as a[p:r]

For example:
a[1:8] = [13, 24, 7, 9, 2, 7, 15, 35], select the first element 13 as the fulcrum

  • Decomposition: a[q] = 13, a[p: q-1] = [7, 9, 2, 7], a[q+1, r] = [24, 15, 35], then know q = 5
  • Sorting: a[p: q-1] = [2, 7, 7, 9] a[q+1: r] = [15, 24, 35] (Actually, instead of starting sorting once, it is constantly recursive, moving values smaller than the current benchmark to the front and values larger than to the back, which is actually sorting)
  • Merge: Place the elements in a[p:q-1] before the fulcrum element 13 and the elements in a[q+1:r] after the fulcrum element.
    The resulting array is: [2, 7, 7, 9, 13, 15, 24, 35]

To avoid any incomprehension, let me give you another example:
It's like if we want to sort the following three numbers: 2 1 3, then we first select base 2, then move the elements less than 2 to the front, the elements larger to the back, and we get 1 2 3
That's the sort.
In the face of a larger array, we do the same thing. The idea of recursive division is reflected in this. Each time we reduce the size of the problem, and finally to only two elements, it is easy to arrange.
And in the process of continuous recursive partitioning, the order of all the numbers has gradually become ordered.
After the first division, it is impossible for numbers larger than the base value to appear in the first half of the elements, and numbers that are also smaller than the base value must be in the first half of the elements.
After the second division,...

The code is as follows:

// Quick Row
// Senior Three Algorithms Course
#include<bits/stdc++.h>
using namespace std;
#Define random (a,b) ((double) rand()/RAND_MAX)*(b-a)+a)//produce a random number of (a,b) intervals
// Random, datum from a[left], to random(a[left], a[right])
template<class T>
int randomizedPartition(vector<T> &a, int p, int r)
{
    srand(int(time(0)));  //Seeds generated each time the current time is used as a random number
    int i = random(p, r);
    swap(a[i], a[p]);
    return Partition(a, p, r);
}
// Datum is a[p], divided
int Partition(vector<int>& a, int low, int high)  //Swap elements smaller than key to the left and elements larger than key to the right
{
    int key = a[low];
    while(low<high)
    {
        while(low<high&&a[high]>key) --high;
        a[low] = a[high];
        while(low<high&&a[low]<=key) ++low;
        a[high] = a[low];
    }
    a[low] = key;
    return low;
}
// Random selection, to avoid extreme situations, uses random. Actually similar, time complexity O(n)-O(n^2)
template<class T>
void randomizedQuickSort(vector<T> &a, int left, int right)
{
    if(left<right)
    {
        int loc = randomizedPartition(a, left, right);
        randomizedQuickSort(a, left, loc-1);
        randomizedQuickSort(a, loc+1, right);
    }
}
template<class T>
void QuickSort(vector<T> &a, int left, int right)
{
    if(left<right)
    {
        int loc = Partition(a, left, right);
        QuickSort(a, left, loc-1);
        QuickSort(a, loc+1, right);
    }
}
int  main()
{
    cout<<"Quick Sort"<<endl;
    int n;
    cout<<"Input Array Size:";
    while(cin>>n && n)
    {
        vector<int> nums(n);
        cout<<"Input Array Element:";
        for(int i=0; i<n; ++i) cin>>nums[i];
        // QuickSort<int>(nums, 0, n-1);
        randomizedQuickSort<int>(nums, 0, n-1);
        for(const int x:nums) cout<<x<<" ";
        cout<<endl;
        cout<<"Input Array Size:";
    }
    system("pause");
    return 0;
}

Run result:

Welcome to my personal blog George's programming cabin Come along with me to experience the whimsical upgrade journey of format programmers!

Tags: quick sort recursion divide and conquer

Posted on Tue, 30 Nov 2021 14:11:50 -0500 by harley1387