栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > PHP

常用的排序算法(一)--快速排序(PHP实现)

PHP 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

常用的排序算法(一)--快速排序(PHP实现)

常用的排序算法系列
  • 常用的排序算法(一)–快速排序(PHP实现)
  • 常用的排序算法(二)–插入排序(PHP实现)
  • 常用的排序算法(三)–冒泡排序(PHP实现)
  • 常用的排序算法(四)–归并排序(PHP实现)
  • 常用的排序算法(五)–选择排序以及优化(PHP实现)

快速排序

假设当前需要从小到大进行排序,快速排序的核心思路是,从当前数组中,找到一个元素作为基准比较值(key),分别从两个方向进行比较。从后往前找,比key小元素放在数组前面。然后从前往后找,比key大的元素放在数组后面。最终两个方向交汇到中间,让key交换到数组的中间位置。

举例说明:

首先,常见的取key方式是,取当前排序数组范围的最左边第一位。(取最右边末尾也可以,但是操作顺序需要调成对称相反的模式)

假设当前需要排序的数组如下:
[ 34, 5, 5, 555, 5, 4, 14, 5, 88, 89, 54]

那么,可以先取34作为一个基准的比较值(key),也就是 key=34

因为我们的key是从前边取的,所以先要从后边(右边)开始往前找数字。
(如果是key从末尾取54,那么就需要先从前边开始往后找数字)

令left为第一位0,令right为最末位数组长度n。

那么,key是从前边取,我们就需要先从right开始,从后往前走。

如果 a[right]>=key(即34),说明是正常的,因为大数字就应该放后面。

因此,right继续往前走,也就是right--。

直到出现 a[right]

继续,不要忘记,快速排序的核心思路是,从当前数组中,找到一个元素作为基准比较值(key),分别从两个方向进行比较。从后往前找,比key小元素放在数组前面。然后从前往后找,比key大的元素放在数组后面。最终两个方向交汇到中间,让key交换到数组的中间位置。

从后往前找小数,已经找到了一个位置了,那么就换一个方向,从前往后找大数。

因此从left开始,从前往后走。

如果 a[left]<=key(即34),说明是正常的,因为小数字就应该放前面。

因此,left 继续往后走,也就是left++。

(这里可以看出,left 和 right 的操作是对称的)

直到出现 a[left]>key, 这就说明有一个大数字出现在了前面,至于它是不是真的属于前面?这个就需要判断 left 和 right 的关系。

如果 left < right ,说明数组的中间位置还夹在 left 和 right 之间,因此 left 标记的位置属于前面,right 标记的位置属于后面。

此时,一个大数字出现在了前面,一个小数字出现在了后面,因此我们直接将其互换,将 ar[left] 和 ar[right] 互换。

互换完之后,当前的标记位left和right 继续两边往中间走。同理,先从right继续从后往前走,直到遇见一个小数字(比key小)。然后换方向从left继续从前往后走,直到遇见一个大数字(比key大)

如果不满足left < right ,而是left = right,说明以及抵达了数值的中心,这时候我们需要做的是把key换到这个中间的地方,这就完成了一轮的快速排序。

完成了这一轮的快速排序之后,就会发现,这个数组可以拆分成左半部分和右半部分。
左半部分是 从 第一位 到 left-1(此时left在中心标记位),里面的数字都比中心的key小。
右半部分是 从 left+1 到 最末位 ,里面的数字都比中心的key大。

因此,我们就可以继续递归地对左半部分和右半部分使用快速排序即可。

直到最终, 开始的left >= 开始right ,说明已经是拆成1个数字了,就没必要再比下去了。

排序的结果就完成了。

整个流程如图所示:

PHP代码运行如图:

PHP版本的实现代码如下

= $right) {//not need to sort
 return;
    }

    //mark the default value
    $first_index = $left;
    $last_index = $right;

    $key = $ar[$left];//default key as first element

    while ($left != $right) {//find 2 swap element to sort into 2 parts

 while ($ar[$right] >= $key && $left < $right) { // [l--r] is [small--big]
     $right--;
 }//until a[r] < key

 while ($ar[$left] <= $key && $left < $right) {
     $left++;
 }//until a[l] > key

 if ($left < $right) { //swap
     echo "
swap ar[$left] = $ar[$left] <-->ar[$right] = $ar[$right]
"; $t = $ar[$left]; $ar[$left] = $ar[$right]; $ar[$right] = $t; } }//finish 2 sorted parts //left == right == mid if ($first_index != $left) {//first_index == mid_index not need to swap, just len = 1 echo "put key ar[$first_index] = $key <--> ar[$left] =$ar[$left]
"; //put mid to first(location of key) $ar[$first_index] = $ar[$left]; //put key into mid $ar [$left] = $key; } print_r(json_encode($ar)); //continue cut and sort //left == right == mid echo "
cut into: $first_index ---- | $left |---- $last_index
"; quick($ar, $first_index, $left - 1); quick($ar, $left + 1, $last_index); }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/226771.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号