【PHP数据结构】其它排序:简单选择、桶排序
这是我们算法正式文章系列的最后一篇文章了,关于排序的知识我们学习了很多,包括常见的冒泡和快排,也学习过了不太常见的简单插入和希尔排序。既然今天这是最后一篇文章,也是排序相关的最后一篇,那我们就来轻松一些,再来学习两个非常简单的排序算法。
简单选择排序
首先是简单选择排序,它划分在了选择类排序下面,不过其实也可以看成是交换类的排序。因为它的核心代码中也是有交换操作的实现的。关于这个排序没有什么太多好说的,每次在遍历中找出最大或者最小的数据,然后将它放到相应的位置就可以了。我们先来看代码,然后再看图示的解析。
function SelectSort($numbers){
$n = count($numbers);
for( $i = 0 ; $i < $n ; $i++){
$k = $i;
for( $j = $i+1 ; $j < $n ; $j++){
if($numbers[$j] < $numbers[$k]){
$k = $j;
}
}
if($k != $i){
list($numbers[$i], $numbers[$k]) = [$numbers[$k], $numbers[$i]];
}
}
echo implode(', ', $numbers), PHP_EOL;
}
SelectSort($numbers);
// 13, 27, 38, 49, 49, 65, 76, 97
代码不复杂吧,可以注意到它也有交换代码的出现。我们使用的是上篇文章中的小彩蛋中的交换方式进行的数据位置的交换。它和冒泡以及快排那种专门的交换型排序算法还是有些许不同的,每次交换的 i 这个位置是不变的,什么意思呢?比如我们现在的 i 是 0 ,也就是说整个序列中最小的数据应该是要放在这个地方的。所以 j 循环是从 i + 1 的位置开始循环的,然后不停地和 i 这个位置的数据进行比较,并不断地更新 k ( k 在一开始是指定为 i 的)。找到最小的数据之后直接将这个数据和 i 的数据交换,这样最小的数据就放到了 i 的位置上了。这就是简单选择排序的核心思想。
这一大段说起来可能会看得比较懵圈。还是看看图吧!

我们依然还是以第一趟的详细过程为例。
k = i ,然后 j 从第二个数据开始遍历
如果发现 numbers[j] 小于 numbers[k] 的数据,也就是更小的数据,就让 k = j
j 循环遍历完成后,k 指向的下标就是最小那个数据,于是交换 k 和 i 的值
一趟排序下来,最小的数据就放到了最前面的位置了
是不是感觉和冒泡有点像呀?确实是很像,冒泡也是一趟外层循环就可以把某个最大或者最小的值放到正确的位置上。不过需要注意的是,冒泡是前后两个数据相比,很有可能每次比较都会发生交换。而选择排序则是以一个下标指针的位置移动来确定数据,最后也只进行一次交换。所以说,它是有选择性的交换,而不是纯粹的一路交换到底。
简单桶排序
真正的桶排序还是比较复杂的,但今天我们学习的这个简单的桶排序则是真的简单的不行。它体现的是一种以空间换时间的方式,具体是怎么换的呢?
function BucketSort($numbers){
$bucketList = [];
$maxValue = max($numbers);
for($i=0;$i <= $maxValue;$i++){
$bucketList[$i] = 0;
}
foreach($numbers as $n){
$bucketList[$n]++;
}
$sortList = [];
foreach($bucketList as $k => $v){
if($v > 0){
for( ; $v > 0 ; $v--){
$sortList[] = $k;
}
}
}
echo implode(', ', $sortList), PHP_EOL;
}
如果是针对的数字类型的排序操作,特别是这个数字基数不大,比如说是类型枚举之类的数据,我们都可以使用这种桶排序的方式。首先我们要看当前最大的数字是几,然后初始化一个数组到这个最大数字的下标,并将所有内容设置为 0 。接着遍历原始的排序数组,给这个要排序数据对应的值加 1 。于是,待排序序列所代表的那些键的值都会变成 1 ,同时,如果有相同的数据,我们使用的是 ++ 操作,这个数据对应的键值就会继续加 1 。具体的过程就如下图所示:

相信这个图已经说明得非常清晰了吧,也不需要我们再深入地解释了吧。这就是这种最简单的桶排序方式,我们也可以将这个桶数组的内容换成二维数据,这样我们就可以实现更复杂数据的排序操作了。不过还是要注意,一定是针对数字类型的哦。我们介绍的这种桶排序其实是真正的桶排序的一种变体,也有人叫它为“计数排序”。
真正更加完备一些的桶排序其实是先将数据分成不同的组,每个组可以看成是一个桶。然后在这个桶内将组内的数据排序,排序完成之后再将这些组(桶)连接起来。它的时间复杂度是接近于 O(n) 的。不过就像我们介绍的这个最简单的桶排序一样,复杂的桶排序也是有许多严苛的要求的,所以虽然它的效果很高,但却并不常见。
总结
今天的内容非常简单吧,简单选择其实也是一种交换排序,但它在大类中还是划归到了选择排序这个类型中。而桶排序是属于基数排序的一种。各种排序其实还有很多,但除了我们学习的这些之外,其它的都会更加的复杂也并不常见,大家有兴趣的可以在下期我们的总结文章中了解到有哪些可以继续深入学习的内容。精彩还在继续,不要错过哦!
测试代码:
参考文档:
《数据结构》第二版,严蔚敏
《数据结构》第二版,陈越
《啊哈!算法》
===============
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
【PHP数据结构】其它排序:简单选择、桶排序的更多相关文章
- 选择排序—简单选择排序(Simple Selection Sort)
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
- 选择排序—简单选择排序(Simple Selection Sort)原理以及Java实现
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
- JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序
1. 前言 算法为王. 想学好前端,先练好内功,只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算 ...
- 算法相关——Java排序算法之桶排序(一)
(代码中对应一个数组的下标),将每个元素放入对应桶中,再将所有元素按顺序输出(代码中则按顺序将数组i下标输出arrary[i]次),即为{0,1,3,5,5,6,9}. 1.2 代码实现 /* *@ ...
- 9, java数据结构和算法: 直接插入排序, 希尔排序, 简单选择排序, 堆排序, 冒泡排序,快速排序, 归并排序, 基数排序的分析和代码实现
内部排序: 就是使用内存空间来排序 外部排序: 就是数据量很大,需要借助外部存储(文件)来排序. 直接上代码: package com.lvcai; public class Sort { publi ...
- Hark的数据结构与算法练习之桶排序
算法说明 桶排序的逻辑其实特别好理解,它是一种纯粹的分而治之的排序方法. 举个例子简单说一下大家就知道精髓了. 假如对11,4,2,13,22,24,20 进行排序. 那么,我们将4和2放在一起,将1 ...
- 八大排序算法之三选择排序—简单选择排序(Simple Selection Sort)
基本思想: 在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换:然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素 ...
- 内部排序->选择排序->简单选择排序
文字描述 简单排序的基本思想是:每一趟在n-i+1(i=1,2,…,n)个记录中选取关键字最小的记录作为有序列表中的第i个记录. 示意图 略 算法分析 简单排序算法中,所需进行记录移动的操作次数较少, ...
- 数据结构与算法之PHP排序算法(桶排序)
一.基本思想 桶排序是将待排序的数据分割成许多buckets,然后每个bucket各自排序,或用不同的排序算法,或者递归的使用bucket sort算法.也是典型的分而治之(divide-and-co ...
- 【C#】1.算法温故而知新 - 简单的桶排序
该算法的时间复杂度是O(M+N),M为桶的个数,N为待排序的个数 缺点: 1.不适用于小数 2.当数值过多,太浪费空间,比如数值范围为0~99999,那需申请100000个变量,也就是要写成a[100 ...
随机推荐
- AI+云原生,把卫星遥感虐的死去活来
摘要:遥感影像,作为地球自拍照,能够从更广阔的视角,为人们提供更多维度的辅助信息,来帮助人类感知自然资源.农林水利.交通灾害等多领域信息. 本文分享自华为云社区<AI+云原生,把卫星遥感虐的死去 ...
- MySQL-17-MHA高可用技术
环境准备 环境准备 至少准备3台独立的虚拟机数据库实例,建议4台 这里实验只准备3台,需要配置好 基于GTID的主从复制,具体怎么配置可以参看前面的章节 db01 10.0.0.51 主库 db02 ...
- Blazor+Dapr+K8s微服务之服务调用
1.1 Dapr环境配置 1.1.1 在开发机安装Docker Desktop并启用Kubernetes 安装过程略,安装好后效果如下:(左下角两个绿色指示Docker和 ...
- RabbitMQ和Elasticsearch的使用笔记
Demo介绍 学习rabbitmq和elasticsearch后的小练习,主要功能点介绍: 1.elasticsearch实现搜索.条件查询和分页: 2.搜索周边酒店信息 3.酒店竞价排名: 4.后台 ...
- 谈谈 Nginx 那点事【一】
为什么突然决定总结Nginx ? 不知不觉8月份又要过完了,时间真是个无情的崽种. 写Nginx 首先,主要源于最近项目部署工作中和公司技术中心的人对接部署相关事宜流程太繁琐了.每个部门有各自的工作安 ...
- 题解 P5038 [SCOI2012]奇怪的游戏
题解 题目 做这题之前,做了一道叫星际战争的题,很容易想到二分 \(+\) 网络流,那么二分啥呢? 我们先推一下式子,因为是对相邻格子加数,那么可以联想到黑白染色类问题. 设有黑色格子 \(B\) 个 ...
- h5与小程序互相跳转,传参和获取参数
1.h5跳转到小程序 首先引入js文件 <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js">< ...
- 【springboot】集成Druid 作为数据库连接池
转自:https://blog.csdn.net/cp026la/article/details/86508139 1. 引言 用户的每一次请求几乎都会访问数据库,访问数据库需要向数据库获取链接,而数 ...
- Java 方法使用
那么什么是方法呢? Java方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 方法的优点 1. 使程序变得更简 ...
- Spring详解------概述
1.什么是 Spring ? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2E ...