快速排序-quickSort

## 快速排序(代码)

写这篇文章之前至少做了不下十遍快排,但现在仍然不能保证一写就A,故记录一下。

partition过程的边界条件不是很好弄,因此面试经常出现。

partition单向划分:三个区域 <=  >  ?

int partition1(vector<int>& nums, int l, int r) { //单向划分
    int i = l-1;
    for (int j = l; j < r; ++j) {
        if (nums[j] <= nums[r])
            swap(nums[++i], nums[j]);
    }
    swap(nums[++i], nums[r]);
    return i;
}

partition双向划分:三个区域  <= ? >=

int partition2(vector<int>& nums, int l, int r) { //双向划分
    int pivot = nums[r];
    int right = r, left = l;
    while (l < r) {
        while (l < r && nums[l] <= pivot) l++;
        nums[r] = nums[l];
        while (l < r && nums[r] >= pivot) r--;
        nums[l] = nums[r];
    }
    nums[l] = pivot;
    return l;
}

partition荷兰国旗问题: 四个区域 < = > ?

代码来自左神。

pair<int, int> partition3(vector<int>& nums, int l, int r) { //荷兰国旗问题 Netherlands
    int less = l - 1;
    int more = r;
    int index = l;
    while (index < more) {
        if (nums[index] < nums[r]) {
            swap(nums[index++], nums[++less]);
        }
        else if (nums[index] == nums[r]) {
            index++;
        }
        else {
            swap(nums[index], nums[--more]);
        }
    }
    swap(nums[more], nums[r]);

    return {less+1, more};    // 1 2 2 2 4 5 3 less+1:最左边的2  more:最右边的2
}

以双向划分为例,递归主函数如下:

void quickSort(vector<int>& nums, int l, int r) {
    if (r <= l)
        return;

    int idx = rand() % (r-l+1) + l;
    swap(nums[r], nums[idx]);
    
    //partition
    int pivotPos = partition2(nums, l, r);

    //recursion
    quickSort(nums, l, pivotPos-1);
    quickSort(nums, pivotPos+1, r);
}

快排不好写,因此面试中问的非常多,记录一下代码。

 

 

 





posted @ 2022-08-10 09:35  Ray-ss  阅读(19)  评论(0编辑  收藏  举报