{"id":1338,"date":"2020-06-14T17:17:29","date_gmt":"2020-06-15T00:17:29","guid":{"rendered":"http:\/\/209.126.2.187\/?p=1338"},"modified":"2020-06-29T21:48:02","modified_gmt":"2020-06-30T04:48:02","slug":"quick-select","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2020\/06\/14\/quick-select\/","title":{"rendered":"Quick Select &#038; Quick Sort"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p><strong>Quick Select<\/strong> is typical technique to select the top k elements (the rest of array is not sorted) from an array in amortized <code>O(n)<\/code> time. If we use a smart way to choose pivot (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Introselect\">Introselect<\/a>), the algorithm is guaranteed to have <code>O(n)<\/code> worst case performance.<\/p>\n\n\n\n<p><strong>Quick Sort<\/strong> is an unstable sort. It has amortized <code>O(nlogn)<\/code> and worst case <code>O(n^2)<\/code> complexity. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Introselect\">Intros<\/a><a href=\"https:\/\/en.wikipedia.org\/wiki\/Introsort\">ort<\/a> combines Quick Sort and Heap Sort and is guaranteed to have <code>O(nlogn)<\/code> worst case performance.<\/p>\n\n\n\n<p>A handy template function in the standard library is shown blow.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">template &lt;class RandomAccessIterator, class Compare>\n  void nth_element (RandomAccessIterator first, RandomAccessIterator nth,\n                    RandomAccessIterator last, Compare comp);\n\/\/ iterator before nth has smaller or equal value; iterator after nth has larger or equal value\n\/\/ nth_element(nums.begin(), nums.begin()+k-1, nums.end())\n\/\/ nums[k-1] will be the kth smallest number. <\/code><\/pre>\n\n\n\n<p>If we want to use the pivot and divide and conquer technique to implement both Quick Select and Sort. Common techniques to avoid infinite loop or wrong answers are listed below.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Choose left as the pivot; <\/li><li>loop while left &lt; right (not &lt;=);<\/li><li>Move right pointer first; <\/li><li>Decrease right only if left is still &lt; right;<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Quick Select<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp line-numbers\">int quick_select(int left, int right, int k, vector&lt;int>&amp; nums) {\n    int pivot = left;\n    int i = left, j = right;\n    while (i &lt; j) {\n        while (i &lt; j &amp;&amp; nums[j] >= nums[pivot]) {\n            j--;\n        }\n        while (i &lt; j &amp;&amp; nums[i] &lt;= nums[pivot]) {\n            i++;\n        }\n        if (i == j) {\n            break;\n        }\n        swap(nums[i], nums[j]);\n        j--;\n    }\n    swap(nums[pivot], nums[i]);\n    if (i - pivot + 1 == k) {\n        return nums[i];\n    } else if (i - pivot + 1 > k) {\n        return quick_select(left, i - 1, k, nums);\n    } else {\n        return quick_select(i + 1, right, k - (i - pivot + 1), nums);\n    }\n}<\/code><\/pre>\n\n\n\n<p>This implementation has the following complexity.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>amortized <code>O(n)<\/code><\/li><li>worst case <code>O(n^2)<\/code> (given an array with all same values and <code>k==n<\/code>; in this case, each time the array only shrinks by one element)<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Quick Sort<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp line-numbers\">void quick_sort(int left, int right, vector&lt;int>&amp; nums) {\n    if (left >= right) {\n        return;\n    }\n    int pivot = left;\n    int i = left, j = right;\n    while (i &lt; j) {\n        while (i &lt; j &amp;&amp; nums[j] >= nums[pivot]) {\n            j--;\n        }\n        while (i &lt; j &amp;&amp; nums[i] &lt;= nums[pivot]) {\n            i++;\n        }\n        if (i == j) {\n            break;\n        }\n        swap(nums[i], nums[j]);\n        j--;\n    }\n    swap(nums[pivot], nums[i]);\n    quick_sort(left, i - 1, nums);\n    quick_sort(i + 1, right, nums);\n}<\/code><\/pre>\n\n\n\n<p>This implementation has the following complexity.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>amortized <code>O(nlogn)<\/code><\/li><li>worst case <code>O(n^2)<\/code> (given an sorted array; in this case, each time the array only shrinks by one element)<\/li><\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Summary Quick Select is typical technique to select the top k elements (the rest of array is not sorted) from an array in amortized O(n) time. If we use a smart way to choose pivot (Introselect), the algorithm is guaranteed to have O(n) worst case performance. Quick Sort is an unstable sort. It has amortized&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,56],"tags":[],"class_list":["post-1338","post","type-post","status-publish","format-standard","hentry","category-alg","category-sort"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1338","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=1338"}],"version-history":[{"count":3,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1338\/revisions"}],"predecessor-version":[{"id":1403,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1338\/revisions\/1403"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=1338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=1338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=1338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}