我一直被这俩弄的头疼,这次好好写了一晚上,给以后的自己。
不管是quick sort还是quick select,核心都是partition 函数,这里给出标准partition函数,记好:
//quick sort
int partition(vector<int> &arr, int left, int right) {
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2];
/* partition */
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
};
<strong> return i; //这里返回i很重要,我试过返回j,结果会有死循环出现</strong>
}
到此,为partition函数的意义。
下面基于此partition,分别讲解quick sort和quick select。
Quick Sort
代码如下:
void sort(vector<int> &nums,int start,int end) {
if (start >= end) {
return;
}
int idx = partition(nums, start, end);
sort(nums,start,idx-1);
sort(nums, idx, end);
}
注意,第一句话很关键,不然会dead lock。每次先partition,得道返回值idx,这里的idx相当于上图里所用的i(个人喜好)。
12/8/2016更新, 纠正一下,这里不是个人喜好,如果用i的话各种例子都可以通过,当partition返回j,quicksort和quickselect就会出错
Quick Select
代码如下:
int select(vector<int> &nums,int start, int end,int k) {
if (start == end) {
return nums[start];
}
int mid = nums[(start+end)/2];
int idx = partition(nums, start, end);
int left = idx-start;
if (left >= k) {
return select(nums, start, idx-1, k);
}
if (left < k) {
return select(nums, idx, end, k-left);
}
return 0;
}
注意,这里int left = idx-start; left表示了左边剩下了几个数。个人犯傻,在这儿徘徊了好久……希望以后面试碰到相关问题可以秒过。!