Quick Sort

时间:2020-04-13 12:59:59   收藏:0   阅读:59

Implementation

#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl

using namespace std;
typedef long long LL;

void qsort(vector<int> &vec, int s, int e) {
    if (s >= e) return;
    int pv = vec[s];
    int l = s, r = e;
    for (int i = s + 1, left = e - s; left > 0; left--) {
        if (vec[i] < pv) {
            vec[l++] = vec[i++];
        } else {
            swap(vec[i], vec[r--]);
        }
    }
    assert(l == r);
    vec[l] = pv;
    qsort(vec, s, l - 1);
    qsort(vec, l + 1, e);
}

int main(int argc, char **argv) {
    srand(time(NULL));
    vector<int> vec(500000);
    for (int i = 0; i < vec.size(); i++) vec[i] = random();
    vector<int> s = vec;

    sort(s.begin(), s.end());
    qsort(vec, 0, vec.size() - 1);

    assert(s == vec);

    return 0;
}

Proof

Correctness of partition

\(s\) is the first index in the subarray of \(vec\), \(e\) is the last index in the subarray of \(vec\).
\(vec[s:e]\) denotes the whole subarray, inclusive.
At the start of the for loop:

We say there are \(x\) elements \(<\) pivot, then there are supposed to be \(e - s - x\) elements \(>=\) pivot.
After the for loop terminates, \(l\) will be \(s + x\), and \(y\) will be \(e - (e - s - x) = s + x\) too, so \(l = r\).
The elements on the left side of \(l \ or\ r\) are all \(<\) pivot, and the elements of the right side of \(l \ or \ r\) are all \(>=\) pivot, then we put the pivot on the position \(l \ or \ r\).
Then all the elements on the left side of the pivot will be smaller than the pivot, and all the elements on the right side of the pivot will be greater than or equal to the pivot.
Thus, the partition is correct.

Correctness of recursion

Proof by induction.
Suppose that \(P(n)\) is a predicate defined on \(n \in [1, \infty)\) meaning the \(Quick Sort\) is correct on a given array sized \(n\).
If we can show that:

  1. \(P(1)\) is true
  2. (\(\forall k < n \ P(k)) \implies P(n)\)

Then \(P(n)\) is true for all integers \(n >= 1\).
\(P(1)\) is obviously true.

To use quicksort to sort an array of size ??, we partition it into three pieces: the first ?? subarray, the pivot (which will be in its correct place), and the remaining subarray of size ??????1. By the way partition works, every element in the first subarray will be less than or equal to the pivot and every element in the other subarray will be greater than or equal to the pivot, so when we recursively sort the first and last subarrays, we will wind up having sorted the entire array.

We show this is correct by strong induction: since the first subarray has ??<?? elements, we can assume by induction that it will be correctly sorted. Since the second subarray has ??????1<?? elements, we can assume that it will be correctly sorted. Thus, putting all the pieces together, we will wind up having sorted the array.[1]


  1. https://cs.stackexchange.com/a/63667 ??

原文:https://www.cnblogs.com/ToRapture/p/12690498.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!