Find Nth Biggest Number Based On QuickSort

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 again
						if (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 :



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值