Last active
August 29, 2015 14:01
-
-
Save sundeepblue/263c70b18e84411c2577 to your computer and use it in GitHub Desktop.
quicksort, quickselect, partition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // various ways of partition function | |
| // see: http://www.liacs.nl/~graaf/STUDENTENSEMINARIUM/quicksorthistorical.pdf | |
| // read the chapter 3 in book: Beautiful Code. It shows how to simplify quicksort to count average comparison numbers. (9/2/2014) | |
| #include <iostream> | |
| using namespace std; | |
| /* | |
| Given an array nums of integers and an int k, partition the array (i.e move the elements in "nums") such that: | |
| All elements < k are moved to the left | |
| All elements >= k are moved to the right | |
| Return the partitioning index, i.e the first index i nums[i] >= k. | |
| */ | |
| // 下面这段代码的好处是,k 不是数组的某个元素,就避免了选轴值 | |
| // 也非常好理解:数组里如果某值比k小,直接跳到下一个。 | |
| // 如果大,就跟数组尾交换,尾缩短。 | |
| // 我认为它可以变成后面所有partition函数的一个子函数。 | |
| int partitionArray(vector<int> &nums, int k) { | |
| // write your code here | |
| int N = nums.size(); | |
| int left = 0, right = N-1; | |
| while (left <= right) { | |
| if (nums[left] < k) { | |
| left++; | |
| } | |
| else { | |
| swap(nums[left], nums[right]); | |
| right--; | |
| } | |
| } | |
| return left++; | |
| } | |
| // ====================================================== | |
| // use one runner. easy to understand. | |
| // edit 8/20/2015 其实感觉还是有点不太容易理解和掌握的。可以先参考上面的代码 | |
| // 段,再来试图理解这个。本质上,有异曲同工之妙 | |
| int partition(int A[], int l, int h) { | |
| int p = h; | |
| int boundry = l; | |
| for(int i=l; i<h; i++) { | |
| if(A[i] < A[p]) | |
| swap(A[i], A[boundry++]); | |
| } | |
| swap(A[p], A[boundry]); | |
| return boundry; | |
| } | |
| // use two runners, had to understand fully | |
| int partition2(int A[], int l, int h) { | |
| int p = l; | |
| int i = l, j = h; | |
| while(i < j) { | |
| while(i < h && A[i] <= A[p]) i++; | |
| while(j >= l && A[j] > A[p]) j--; | |
| if(i < j) swap(A[i++], A[j--]); | |
| } | |
| swap(A[j], A[p]); | |
| return j; | |
| } | |
| // use two runners, version 2. easy to understand | |
| int partition3(int A[], int l, int h) { | |
| int p = l; | |
| int i = l, j = h+1; | |
| while(true) { | |
| while(A[++i] < A[p]) if(i == h) break; | |
| while(A[p] < A[--j]) if(j == l) break; | |
| if(i >= j) break; | |
| swap(A[i], A[j]); | |
| } | |
| swap(A[j], A[p]); | |
| return j; | |
| } | |
| // quicksort with three-way partition. | |
| // used for arrays with many equal keys | |
| void quicksort3way(int A[], int l, int h) { | |
| if(l >= h) return; | |
| int lt = l, i = l+1, gt = h; | |
| int v = A[l]; | |
| while(i <= gt) { | |
| if(A[i] < v) swap(A[lt++], A[i++]); | |
| else if(A[i] > v) swap(A[i], A[gt--]); | |
| else i++; | |
| } | |
| quicksort3way(A, l, lt-1); | |
| quicksort3way(A, gt+1, h); | |
| } | |
| void quicksort(int A[], int l, int h) { | |
| if(l >= h) return; | |
| int p = partition2(A, l, h); | |
| quicksort(A, l, p-1); | |
| quicksort(A, p+1, h); | |
| } | |
| int quickselect(int A[], int N, int k) { | |
| //shuffle(A, N); | |
| int l = 0, h = N-1; | |
| while(l < h) { | |
| int p = partition(A, l, h); | |
| if(p == k) return A[k]; | |
| else if(p < k) l = p + 1; | |
| else if(p > k) h = p - 1; | |
| } | |
| return A[k]; | |
| } | |
| int main() { | |
| int A[] = {2,9,2,4,2,4,1,7,-1,0,3,8}; | |
| quicksort(A, 0, 11); | |
| for(int i=0; i<12; i++) | |
| cout << A[i] << " "; | |
| } | |
| // my another version: maybe not right | |
| int partition4(int A[], int low, int high) { | |
| int p = low; | |
| int i=low, j = high; | |
| while(i < j) { | |
| while(i <= high && A[i] <= A[p]) i++; | |
| while(j >= low && A[j] > A[p]) j--; | |
| if(i < j) swap(A[i++], A[j--]); | |
| } | |
| swap(A[j], A[p]); | |
| return j; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment