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

常用的排序算法(五)--选择排序以及优化(PHP实现)

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

常用的排序算法(五)--选择排序以及优化(PHP实现)

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

选择排序以及优化

选择排序也是一种常用的简单的排序算法,虽然算法的复杂度是和冒泡一样都是O(n^2),但性能还是稍微好一些的,在一些简单的场景中选择排序非常好用。

假设当前需要进行排序,选择排序的核心思路是,找到一个最大或者最小的标记位,将其与当前需要排序的位置交换他们的值,这样的交换就会比冒泡更加有效率。

举例说明:
假设当前需要排序的数组如下:
[ 34, 5, 555,14, 88, 5 ]

首先我们要用一个循环来遍历这个数组,用来做排序的位置交换。
默认呢,假设当前取到的第一个数字是最小的,我们记录下编号即可,后面找到真正的最小值编号我们再更新即可。

第一次我们取第一个数 34 作为当前的最小值,记录下他的 最小值编号 0。

接着,我们要再用一个循环,去找数组后面部分的需要交换的位置(也就是找到真正的最小值编号),当前排序的,是编号0位置,因此我们从编号1开始往后找,如果发现后面有小于等于编号位置的值,我们就更新这个最小值编号

往后找,发现 5 比 34 小,于是最小值编号就变成了1 。
继续往后找,发现编号5的5等于当前最小值5,于是最小值编号就变成了5 。

最后,我们来判断一下最小值编号和最开始有没有变化,如果有变化,说明找到了一个更小的数再后面,那就应该进行交换操作把它弄到前面来。如果没有变化,就是说后面没有更小的了,我们不需要交换了。往后开始排下一个位置即可。

此时最小值编号是5,已经不等于最开始我需要排序的位置0了,所以我们进行一个交换,得到的结果为:

[ 34, 5, 555,14, 88, 5 ] --> 排序一次后–> [ 5, 5, 555,14, 88, 34 ]

完成之后,我们排下一个位置,也就是位置编号1,重复上面的步骤即可。

位置1的5,找不到更小的,不理
[ 5,5, 555,14, 88, 34 ]

位置2的555,与位置5的34交换
[ 5, 5, 555,14, 88, 34 ] --> [ 5, 5, 34 ,14, 88, 555 ]

位置3的14,找不到更小的,不理
[ 5, 5, 34 ,14, 88, 555 ]

位置4的88,找不到更小的,不理
[ 5, 5, 34 ,14, 88, 555 ]

位置5的555,找不到更小的。不理
[ 5, 5, 34 ,14, 88,** 555** ]

这样我们就完成了排序的过程。写程序的时候要特别注意这个编号的概念,我们的目的是为了找编号,然后将对应标号的值去做交换,并不是直接去用这个最小值。

PHP实现排序过程如下:

优化

可以看出,我们通过找最小值的下标编号,来减少中间不必要的数组元素交换操作,而我们每次只是标记一个最小的值,通过一个方向来排序。

因为最大最小其实是一个对称的操作判断,有没有方式可以更快完成这个流程呢?

当然是有的,我们可以把原来单路的选择排序,改成双路的,每次标记一个最小和一个最大的值,通过两个方向来排序。

每次排序的进行两个标记,一个是找出范围里的最大值,另一个是找出范围里的最小值,相当于是同时在做一个两个方向的排序,每次排序能稳定的排出来两个值。

下一次循环的时候,缩减查找的排序范围,左边界的值加一,右边界的值减一,直到相遇。

这里其实就有一点点快排的味道出来了,快排是有分治思想在里面的,所以会更加快。

PHP排序过程如下:

代码

PHP选择排序 https://github.com/ParrySMS/Exp/blob/master/Algorithm/sort/SelectionSort.php

PHP选择排序-双路优化 https://github.com/ParrySMS/Exp/blob/master/Algorithm/sort/SelectionSortImp.php

PHP选择排序
";
print_r(json_encode($ar));
echo "
"; selection($ar); echo "result:
"; print_r(json_encode($ar)); echo "
"; function selection(array & $ar, $len = null) { if ($len === null) { $len = sizeof($ar); } for ($i = 0; $i < $len - 1; $i++) { $min = $i; //consider i as min_index for ($j = $i + 1; $j < $len; $j++) {//find min_index if($ar[$j]<=$ar[$min]){ $min = $j; } } //check min_index and swap if($min!=$i){//changeSelectionSort.php $t = $ar[$i]; $ar[$i]=$ar[$min]; $ar[$min] = $t; } echo "after 1 times:
"; print_r(json_encode($ar)); echo "
"; } }

PHP选择排序-双路优化
";
print_r(json_encode($ar));
echo "
"; selection($ar); echo "result:
"; print_r(json_encode($ar)); echo "
"; function selection(array & $ar, $len = null) { if ($len === null) { $len = sizeof($ar); } for ($left = 0, $right = $len - 1; $left < $right; $left++, $right--) { $min = $left; //consider left as min_index and max_index $max = $right; for ($j = $left + 1; $j <= $right; $j++) {//find min_index max_index if ($ar[$j] <= $ar[$min]) { $min = $j; } if ($ar[$j] >= $ar[$max]) { $max = $j; } } //check min_index and swap if ($min != $left) { $t = $ar[$left]; $ar[$left] = $ar[$min]; $ar[$min] = $t; } if ($max != $right) { $t = $ar[$right]; $ar[$right] = $ar[$max]; $ar[$max] = $t; } echo "after 1 times:
"; print_r(json_encode($ar)); echo "
"; } }

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

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

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