算法-快速排序(最好的方法是将代码打断点一步一步走走)

算法-快速排序

原理:(按从小到大排序为例)

考察:双指针+递归分支(本质是一个创建二叉树,搜索树的过程)

方法一:

  1. 取数组的随意一个数为基准数,(此例子选第一个元素 arr[0]为基准数)

  2. 将数组中的其他元素与这个基准数比较,比基准数小的放到一个数组中,比基准数大的放到另一个数组中;

  3. 通过递归的方式重复循环上述操作;

    比如数组:[3,2,9,1,10]

    1. 第一步:随便取出数组中的一个数(此例选数组中第一个元素arr[0]即3),数组剩下[2,9,1,10]

    2. 第二步:遍历数组[2,9,1,10],比3小的放到一个数组中,比如left:[2,1],比3大的放到另一个数组中 right:[9,10]

    3. 第三步:数组left:[2,1],再取一个基准数2,剩下数组[1],比2小,放到left;数组right:[9,10],再取一个基准数9,剩下数组[10],比9大,放到right

    4. 第四步:如果左边或者右边的数组长度仍然大于1,继续递归上面的操作,如果俩数组的长度都小于等于1,则结束递归。

    5. 拼接

    代码实现:
    let arr = [3,2,9,1,10]
    function quickSort(arr){
        if(arr.length<2) return arr;
        let base = arr[0]
        let left = []
        let right = []
        arr = arr.splice(1)//把arr[0]删掉
        arr.forEach(item=>{
            if(item<base){
                left.push(item)
            }else{
                right.push(item)
            }
        })
        return quickSort(left).concat(base,quickSort(right))
        
    }
    quickSort(arr)
    

想要更好的知道代码的执行过程,建议打断点一步一步走走看,一目了然!!!!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法二:
  1. 数组[2,3,1,5,6,4],创建两指针,一个指向头一个指向尾,再确定一个基准数(此例子取2为基准数)。
    在这里插入图片描述

  2. 开始第一次的递归处理,尾指针先从右往左扫,扫到第一个小于(注意是小于,而不是小于等于哦)基准数的位置停住,这时候头指针再从左往右扫,扫到第一个大于基准数的位置停住,这时候是下面的图示状态:
    在这里插入图片描述

交换两个指针所指的数,成为了下面的状态:
在这里插入图片描述

  1. 两个数交换完毕,右指针此时指的是arr[2] = 3, 左指针指着arr[1] = 1;交换完毕后右指针继续从当前位置往左扫,扫到1的时候发现和左指针相遇了,那么这个时候就结束左右指针的扫描,左右指针同时指着arr[1] = 1,即:
    在这里插入图片描述

    此时退出循环扫描的过程,交换基准数与左右指针同时所指的数的位置,开头说了,基准数我选择的是arr[0] = 2, 指针指的是arr[1] = 1; 交换过后就变成了:

    在这里插入图片描述

    这时候就发现基准数已经出现在了它排完序后应该在的位置(排完序后是[1,2,3,4,5,6],2出现在了第2位),比这个基准数小的数组出现在了它的左边([1]出现在了2的左边),比基准数大的出现在了它的右边([3,5,6,4]出现在了2的右边)。

  2. 之后的过程就是对左右数组的分别递归处理。

代码实现:
function quickSort(arr, begin, end) {
    //递归出口
    if(begin >= end)
        return;
    var l = begin; // 左指针
    var r = end; //右指针
    var temp = arr[begin]; //基准数,这里取数组第一个数
    //左右指针相遇的时候退出扫描循环
    while(l < r) {
        //右指针从右向左扫描,碰到第一个小于基准数的时候停住
        while(l < r && arr[r] >= temp)
            r --;
        //左指针从左向右扫描,碰到第一个大于基准数的时候停住
        while(l < r && arr[l] <= temp)
            l ++;
        //交换左右指针所停位置的数
        [arr[l], arr[r]] = [arr[r], arr[l]];
    }
    //最后交换基准数与指针相遇位置的数
    [arr[begin], arr[l]] = [arr[l], arr[begin]];
    //递归处理左右数组
    quickSort(arr, begin, l - 1);
    quickSort(arr, l + 1, end);
}

var arr = [2,3,4,1,5,6]
quickSort(arr, 0, 5);
console.log(arr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值