算法之快速排序(Quick Sort)

1. 算法简介

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

2. 算法描述和实现

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

  1. 从数列中挑出一个元素,称为 “基准”(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
    再给大家放一副图片,让大家更容易理解,图片如下所示:
    快速排序图
    js代码如下所示:
    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
    40
    41
    42
    43
    44
    45
    46
    47
    var arr = [3,2,4,5,7,8,10,9,1,6];
    var count = 0;
    function compare(a,b,c){ // 优化之后
    if(a > b){
    if(b > c){
    return b;
    }
    return a > c ? c : a;
    }
    if(a > c){
    return a;
    }
    return b > c ? c : b;
    }

    function fast(arr){
    ++count;
    if(arr.length <= 1){
    return arr;
    }
    var len = arr.length;
    var center = arr[Math.floor(len/2)];
    var base = compare(arr[0],center,arr[len-1]);
    // var base = arr[0];
    var left = [];
    var middle = [];
    var right = [];
    for(var i = 0 ; i < len ; i++){
    if(arr[i] < base){
    left.push(arr[i]);
    }else if(arr[i] == base){
    middle.push(arr[i]);
    }else{
    right.push(arr[i]);
    }
    }
    if(left.length == 0){
    return left.concat(middle,fast(right));
    }else if(right.length == 0){
    return fast(left).concat(middle,right);
    }else if(left.length == 0 && right.length == 0){
    return left.concat(middle,right);
    }
    return fast(left).concat(middle,fast(right));
    }
    console.log(fast(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    console.log(count) // 10