快速排序算法

人生当中成功只是一时的,失败却是主旋律。但是如何面对失败,却把人分成了不同的样子,有的人会被失败击垮,有的人能不断的爬起来继续向前...我想真正的成熟应该并不是追求完美,而是直面自己的缺憾,这才是生活的本质

目录

原理

图解

代码


原理

  • 从数组中挑选一个元素作为基准值(pivot).一般选第一个元素
  • 重新排序数组,将比基准值小的元素放到基准值前面,比基准值大的元素放到基准值后面,结束之后,这个基准值就在数组的中间位置,这个称谓分区操作.
  • 把基准值前面和后面的元素递归重复上面步骤.

 图解

 

 

代码

<?php

// 快速排序
function quickSort(&$arr, $left, $right){
    if($left>$right) return $arr;
    // 选择一个基准值,这里取得是第一个值
    $basic = $arr[$left];
    // $i表示左侧比基准值大的数位置
    $i = $left;
    // $r表示右侧比基准值小的数位置
    $r = $right;
    // 当左侧和右侧没有重叠就一直执行,当停止执行,说明已经重叠,把基准值放进去就可以
    while ($i<$r)
    {
        // 从数组最后开始比较,当比基准值大的时候就让下标-1,直到遇到比基准值小的.
        while($i<$r && $arr[$r]>=$basic) $r--;
        // 已经遇到比基准值小的,把这个数移动到左侧的空位置
        // $i 可以理解为左侧的空位
        $arr[$i] = $arr[$r];

        // 从数组开始比较,当比基准值小的时候就让下标+1,直到遇到比基准值大的.
        while($i<$r && $arr[$i]<$basic) $i++;
        // 此时$i下标就是左侧比基准值大的数的所在位置
        // $r 理解为右侧空位,把左侧的值放到右侧空位
        $arr[$r] = $arr[$i];
    }
    // 跳出循环,说明$i和$r相等了,也就是下标在同一位置了,把基准值补充到当前位置.
    $arr[$i] = $basic;
    // 递归对基准值($i)左侧的数据进行重新排序
    quickSort($arr, $left, $i-1);
    // 递归对基准值($i)右侧的数据进行重新排序
    quickSort($arr, $i+1,$right);

}

function bubbleSort(&$arr)
{
    $n = count($arr);
    for ($i = 0; $i < $n; $i++)
    {
        for ($a = 0; $a < $n-$i-1; $a++)
        {
            if($arr[$a]>$arr[$a+1])
            {
                $tmp = $arr[$a];
                $arr[$a] = $arr[$a+1];
                $arr[$a+1] = $tmp;
            }
        }
    }
}


$arr = [10,2,0,3,5,45,89];
for ($i = 0; $i<10000; $i++) {
    array_push($arr, mt_rand(20,100000));
}

$startTime = microtime(true);
// 1W条数据下,快速排序大约在0.02S左右,可以看出在数据量大的情况下差距还是非常大的
// 快速排序
quickSort($arr, 0, count($arr)-1);
// 1W条数据的情况下 冒泡排序大概是3S左右
// 冒泡排序
// bubbleSort($arr);
$endTime = microtime(true);

print_r($endTime-$startTime);
print_r($arr);
<?php

// 同样也是快速排序,写法不同
function quickSort($arr)
{
    if(count($arr)<=1) return $arr;
    $basic = $arr[0];
    $left = [];
    $right = [];

    for($i=1; $i<count($arr); $i++)
    {
        if($arr[$i] >= $basic) $right[] = $arr[$i];
        if($arr[$i] < $basic) $left[] = $arr[$i];
    }
    $leftArr = quickSort($left);
    $rightArr = quickSort($right);
    
    return array_merge($left, array($basic), $right);
}
# Python
def quicksort(arr, left, right):
    # 下面解释是针对当 left=right时,执行过程
    # 当左面和右面下标重叠时,继续执行
    if left > right:
        return
    l = left
    r = right
    basic = arr[left]
    
    # 当执行到这里,如果l<r不成立,那么说明l=r了,因为上面条件是left>right,也就是left<=right,小于不成立,所以是等于.
    while l<r:
        while l<r and arr[r]>=basic:
            r-=1
        arr[l] = arr[r]
        while l<r and arr[l]<=basic:
            l+=1
        arr[r] = arr[l]
    # 当重叠了.直接把基准值赋值到当前数组中.
    arr[l] = basic

    quicksort(arr, left, l-1)
    quicksort(arr, l+1, right)

if __name__ == '__main__':
    arr = [10,1,2,35,8,9]
    quicksort(arr,0,len(arr)-1)
    print(arr)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值