JavaScript快速排序

实现原理

通过一趟排序将要排序的数据分割成独立的两部分:

  1. 分割点base默认取一开始数组最左边的值
  2. 经过左右指针的分区判断,令所有比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。
  3. 之后把小于基准值元素的子数列和大于基准值元素的子数列排序。

写法一:递归+自建函数

function division(array,left,right){
    //以最左边的数为基准,取数值
    let base=array[left];
    while(left<right){
        //从序列右端开始,向左遍历,直到找到小于base的数
        while(left<right && array[right] >= base) right--;
        //找到比base小的元素,将这个元素放到最左边的位置
        array[left]=array[right];

        //从序列左端开始,向右遍历,直到找到大于base的数
        while(left<right && array[left] <= base) left++;
        //找到比base大的元素,将这个元素放到最右边的位置
        array[right]=array[left];
    }
    //最后将base放到left位置。此时,left位置的左侧数值应比base小;
    //而left位置的右侧数值比base大
    array[left]=base;
    //返回base下标
    return left;
}

function QuickSort(array,left,right) {
    //左下标一定小于右下标
    if(left<right){
        //对数组进行分割,取下次分割的基准下标
        let base=division(array,left,right);
        //继续对基准下标的左侧进行递归切割,以保最后的排序
        QuickSort(array,left,base-1);
        //继续对基准下标的右侧进行递归切割,以保最后的排序
        QuickSort(array,base+1,right);
    }
    return array;
}

var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(QuickSort(arr,0,arr.length-1));
  • 时间复杂度:\(O(NlogN)\)
  • 空间复杂度:\(O(logN)\)

不稳定的排序算法

写法二:利用array的内置函数

其实base一开始可以随便选,这次我选正中间,利用splice()函数单独切割出来,再比较左右子分区的情况。之后就重新用concat()合并就好了,当然这样的写法会加大时间的开销。

var QuickSort2=function(arr){
    if(arr.length<=1) return arr;
    var baseIndex = Math.floor(arr.length/2);
    //单独取出来
    var base=arr.splice(baseIndex,1)[0];
    let left=[],right=[];
    for(let i=0;i<arr.length;i++){
        if(arr[i]<base){
            left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
    return QuickSort2(left).concat([base],QuickSort2(right));
}

var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48];
console.log(QuickSort2(arr));

posted @ 2022-07-17 14:36  帕图纳克斯  阅读(172)  评论(0)    收藏  举报