# 非递归快排

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
Last Updated: 6/27/2023, 7:40:45 PM