快排的各种写法:递归/非递归 + 双指针/挖坑法

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

//双指针法
int part2(vector<int>& arr, int l, int r){
    int pivot = arr[l];
    int i = l, j = r; 
    while(i < j){   //循环不变式必须为 i < j,因为设为 i<= j 时,会越界
        while(i < j && arr[j] >= pivot) j--;  // 设为 i<= j 时,例 [2, 6, 5, 7, 4] 会出数组边界最后 j = -1
        while(i < j && arr[i] <= pivot) i++;
        swap(arr[i], arr[j]);
    }
    swap(arr[i], arr[l]);
    return i;
}
//挖坑法
int part(vector<int>& arr, int l, int r){
    int pivot = arr[l];
    while(l < r){
        while(l < r && arr[r] >= pivot) r--;
        arr[l] = arr[r];
        while(l < r && arr[l] <= pivot) l++;
        arr[r] = arr[l];
    }
    arr[l] = pivot;
    return i;
}
//非递归法--栈模拟递归,栈中存的是递归调用中的[l, pivot-1], [pivot+1, r]
void quickSort2(vector<int>& arr, int l, int r){
    stack<int> S;  
    S.push(l);
    S.push(r);
    while(!S.empty()){
        int en = S.top();
        S.pop();
        int beg = S.top();
        S.pop();
        int pivot = part(arr, beg, en);
        if(beg < pivot - 1){  //等于递归方法中的边界判断,要使 l < r 才执行part(arr, l, r);
            S.push(beg);
            S.push(pivot-1);
        }
        if(en > pivot + 1){
            S.push(pivot+1);
            S.push(en);
        }
    }
}
//递归法
void quickSort(vector<int>& arr, int l, int r){
    if(l >= r) return;
    int p = part2(arr, l, r);
    quickSort(arr, l, p-1);
    quickSort(arr, p+1, r);
}

int main(){
    int n;
    vector<int> arr(n);
    cout << "array size: " << endl;
    cin >> n;
    cout << "array: " << endl;
    for(int i = 0; i < n; i++){
        cin >> arr[i];
    }
    quickSort2(arr, 0, n-1);
    for(int i = 0; i < n; i++){
        cout << arr[i] << " ";
    }
    cout << endl;
}

 

posted @ 2020-06-11 19:49  萌新的学习之路  阅读(374)  评论(0编辑  收藏  举报