# 非递归快排
function quickSort(num) {
_quickSort(num, 0, num.length - 1); // 将整个num数组快速排序,left和right分别指向数组左右两端。
// console.log(num);
}
function _quickSort(num, left, right) {
var list = [[left, right]]; // 将[left,right]存入数组中,类似于递归入栈
while (list.length > 0) {
// 若list不为空,循环弹出list最后一个数组进行快排
var now = list.pop(); // 弹出list末尾。(也可用list.shift()取出list第一个数组,但在数据量较大时,这种方式效率较低)
if (now[0] >= now[1]) {
// 若左右指针相遇,待排序数组长度小宇1,则无需进行快排(注意不能写成now[0]==now[1],这里now[0]是有可能大于now[1]的
continue;
}
var i = now[0],
j = now[1],
flag = now[0]; // 以下与递归方法相同,请参考上面的递归详解
while (i < j) {
while (num[j] >= num[flag] && j > flag) j--; // j不断左移,找到在num[flag]右侧且比它大的数。
if (i >= j) {
break; // 由于j可能已被改变,需再次判断i与j是否碰头。
}
while (num[i] <= num[flag] && i < j) i++; // i不断右移,找到且比基数小的数,且i不能与j碰头。(由于两次交换已合并,此处不需要使得i在flag左侧)
// num[flag] num[j] num[i]三者换位,可用ES6语法糖[num[flag],num[j],num[i]] = [num[j],num[i],num[flag]];
console.log(i, j, flag);
let temp = num[flag];
num[flag] = num[j];
num[j] = num[i];
num[i] = temp;
flag = i; // 基数已经在原num[i]的位置,flag同时也要赋值成i
console.log(num);
}
list.push([now[0], flag - 1]); // 将flag左边数组作为待排序数组,只需将左右指针放入list即可。
list.push([flag + 1, now[1]]); // 将flag右边数组作为待排序数组,只需将左右指针放入list即可。
}
}
console.log(quickSort([9, 17, 0, 6, 10, 5]));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
← 阿里面试题 面试题 08.01. 三步问题 →