Find Nth Biggest Number Based On QuickSort

来源:互联网 发布:手机淘宝1元抢购在哪 编辑:程序博客网 时间:2024/06/05 02:42

First,  the recursive version of Quick sort algorithm:

<script>function partition(arr, low, high){var pivot = arr[low];while (low < high){while (low < high) {if (arr[high] <= pivot ){arr[low] = [arr[high], arr[high]=arr[low]][0];break;}--high;}while (low < high){if (arr[low] > pivot ){arr[high] = [arr[low], arr[low] = arr[high]][0];break;}++low;}}return low;}function Qsort_recursive(arr, low, high){if ( low < high ){var loc = partition(arr, low, high);Qsort_recursive(arr, low, loc-1);Qsort_recursive(arr, loc+1, high);}}function QuickSort(arr){Qsort_recursive(arr, 0, arr.length-1);return arr;}console.log(QuickSort([45, 79, 30, 2, 98, 10, 3, 2, 3, 18]));</script>

Turn the recursive Quick Sort into non-recursive form is basically matter of traversing the binary-tree in preorder, so my version of non-recursive form of Quick Sort algorithm is as such:

function Qsort_nonrecursive(arr, low, high){var stack = [], loc,cur = { low: low, high: high, flag: 0, loc: undefined };stack.push(cur);while (stack.length != 0) {cur = stack.pop();if (cur.flag == 0 && cur.low < cur.high){cur.loc = loc = partition(arr, cur.low, cur.high);cur.flag = 1;}if (cur.flag == 1) {if (cur.low < loc - 1){stack.push(cur);stack.push({ low: cur.low, high: cur.loc -1, flag: 0, loc: undefined});continue;} else { //cur.low >= loc-1, no more leftbrach push operation;if (cur.high > loc+1){stack.push(cur);stack.push({low: cur.loc+1, high: cur.high, flag: 0, loc: undefined});} else { //when cur.high <= loc+1, no more right branch push operation; no need to push cur node againif (stack.length != 0 ) {stack[stack.length-1].flag == 2 &&(stack[stack.length -1].flag = 3) ||(stack[stack.length -1].flag = 2 );}}continue;}}if (cur.flag == 2){ //flag 2, left branch handled;if ( cur.loc+1 < cur.high) {stack.push(cur);stack.push({ low: cur.loc+1, high: cur.high, flag: 0, loc: undefined });} else {if (stack.length != 0){stack[stack.length -1].flag = 3;}}}if (cur.flag == 3) { //flag 3, return from right branch;if (stack.length != 0){stack[stack.length -1].flag == 1 &&(stack[stack.length -1].flag = 2) ||(stack[stack.length -1].flag = 3)}}} //end of while}function QuickSort_nonrecursive(arr){var low = 0, high = arr.length-1;Qsort_nonrecursive(arr, low, high);return arr;}console.log(QuickSort_nonrecursive([45, 79, 30, 2, 98, 10, 3, 2, 3, 18]))


output:


so, based on understanding of above, my version of find Nth biggest number in a array based on Quick sort in recursive as well as non-recursive implementation is below:

<script>function partition_reversed(arr, low, high){var pivot = arr[low];while (low < high ){while ( low < high ){ if (arr[high] >= pivot ){arr[low] = [arr[high], arr[high] = arr[low] ][0];break;}--high;}while ( low < high ) {if (arr[low] < pivot ){arr[high] = [arr[low], arr[low] = arr[high]][0];break;}++low;}}return low;}var K, result;function findK_QS_recursive(arr,low, high){if (low == high){return result = arr[low];}if (low < high){var loc = partition_reversed(arr, low, high);if (loc == K)return result = arr[loc];if (loc < K){arguments.callee(arr, loc+1, high);} else {arguments.callee(arr, low, loc-1);}}}function findK_QS_base1(arr, N){if (N > arr.length)throw "N should NOT exceed arr's length";K = N - 1;findK_QS_recursive(arr, 0, arr.length-1);console.log("recursive: the ", N,"th bigest is ", result, "in ", arr);}var c = [27,30, 12, 16, 10, 7, 49, 79];var d = [56, 32, 12, 1, 10, 5, 19, 8, 3, 90, 100, 48, 67];findK_QS_base1(c, 4);findK_QS_base1(d, 6);function findK_QS_nonrecursive(arr, N){var stack = [], ret,M = N -1,low = 0, high = arr.length -1;stack.push({ low: low, high: high, loc: undefined, flag: 0});while (stack.length != 0){var cur, loc;cur = stack.pop();if ( cur.flag == 0){cur.loc = loc  = partition_reversed(arr, cur.low, cur.high);cur.flag = 1; //1: currrent node calculated;if (loc == M)return ret = arr[loc];}if (cur.flag == 1){if ( loc < M){if ( cur.loc+1 < cur.high){stack.push(cur);stack.push({ low: cur.loc+1, high: cur.high, loc: undefined, flag: 0 });} else { if (cur.loc+1 == cur.high){return ret = arr[cur.high];}console.log("Error1", cur);throw new Error("Error1");}} else if ( loc > M) {if (cur.low < cur.loc-1){stack.push(cur);stack.push({ low: cur.low, high: cur.loc -1, flag: 0, loc: undefined});} else {if (cur.low == cur.loc-1){return ret = arr[cur.low];}console.log("Error2", cur);throw new Error("Error2");}}}}}var Z = 4, Y = 6;var G = findK_QS_nonrecursive(c, Z);console.log("nonrecursive: the ", Z, "th bigest is ", G, "in ", c);var H = findK_QS_nonrecursive(d, Y);console.log("nonrecursive: the ", Y, "th bigest is ", H, "in ", d);</script>
the output is :



原创粉丝点击