Let Quick Sort Stack Overflow

Keywords: C++ less

The idea of quick sorting is dichotomy. Ideally, every dichotomy can divide the data sequence equally, so the recursive hierarchy is logN. The worst case is that every dichotomy is divided into 0 and n, which will be infinitely recursive, and eventually stack overflow. Or each time is divided into 1 and n-1, which will recurse n times. If n is larger, stack overflow will occur.
So the quick sorting dichotomy method can not be simply written.
For example, the following quick sort method can solve almost all data sequences, but if a piece of data is manufactured artificially, it can overflow the stack.

#include <stdio.h>
#include <vector>
using namespace std;


static inline void swap(int *p, int *q)
{
    int t = *p;
    *p = *q;
    *q = t;
}

void quick_sort1(int *A, int head, int end)
{
    if(head >= end)
    {
        return;
    }

    int x = A[(head + end) / 2];
    int left = head;
    int right = end;

    while(left <= right)
    {
        while(left < end)
        {
            if(A[left] >= x)        // when >= -> break
            {
                break;
            }
            left++;
        }
        while(right > head)
        {
            if(A[right] <= x)        // when <= -> break
            {
                break;
            }
            right--;
        }

        if(left <= right)        // when <=, go on swap and ++ --, until left > right,
        {
            swap(&ar[left], &ar[right]);
            left++;
            right--;
        }
    }

    quick_sort1(A, head, right);
    quick_sort1(A, left, end);
}

int main()
{
    vector <int> v = {2, 3};
    int min = 1;
    int n = 40000;

    for(int i = 0; i < n; i++)
    {
        v.insert(v.begin(), min);

        int middle_index= (0 + (v.size() - 1)) / 2;
        int t = v[middle_index];
        v[middle_index] = v[0];
        v[0] = t;

        min--;
    }

    n += 2;
    int ar[n];
    for(int i = 0; i < n; i++)
    {
        ar[i] = v[i];
    }

    quick_sort1(ar, 0, n - 1);

    for(int i = 0; i < n; i++)
    {
        printf("%d \n", ar[i]);
    }

    return 0;
}

The method of manufacturing data sequence is as follows (in fact, the inverse of the above dichotomy):
The first step is to randomly construct an array ar{2,3} and then add a number of {1,2,3} at the head of the array to get {1,2,3}. Then the value of the first element ar[0] and the element ar[1] in the middle of AR is exchanged to get {2,1,3}.
Step 2: Add a value less than 0 of all elements in the array to get {0, 2, 1, 3} and then interchange the value of the first element of ar[0] and the middle element of ar[1] to get {2, 0, 1, 3}.
Repeat the second step, and if you do it 40,000 times, you will get an array of 4,000 elements, which will make the previous quick sorting method too deep and overflow the stack.

So if the dichotomy of quick sorting only specifies a number a and puts the elements of <= a on the left and >= a on the right with some rule, then for this rule, we can use an opposite method to manufacture data artificially and overflow the sorting stack.

Posted by freddyw on Tue, 08 Oct 2019 01:18:03 -0700