快速排序-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); }
快排不好写,因此面试中问的非常多,记录一下代码。