排序算法
十大排序算法:参考链接
1. 冒泡排序
重复地走访过要排序的数列,一次比较两个元素。如果第一个比第二个大,顺序调换。
这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
$arr = [2, 10, 7, 20, 44, 38, 100, 1, 20];
$count = count($arr);
for ( $i=0; $i<$count-1; $i++) {
for ($j=0; $j<$count-1-$i; $j++) { // 设置次数
if ($arr[$j] > $arr[$j+1]) { // 前者和或者比较
$temp = $arr[$j]; // 交换值
$arr[$j] = $arr[$j+1];
$arr[$j+1] = $temp;
}
}
}
2. 选择排序
比较序列中最小的值,记录键值,排列到起始位置。
$arr = [5, 44, 89, 10, 2, 63, 9, 1, 20];
$count = count($arr);
for ($i=0; $i<$count-1; $i++) {
$minIndex = $i; // 初始key值
for ($j=$i+1; $j<$count; $j++) { // 用初始值,循环比较
if ($arr[$j] < $arr[$minIndex]) {
$minIndex = $j; // 较小的重新赋值
}
}
$temp = $arr[$i]; // 位置切换
$arr[$i] = $arr[$minIndex];
$arr[$minIndex] = $temp;
}
3. 插入排序
根据当前key值判断是否大于下一个value值,后进行替换
$arr = [9, 20, 80, 2, 6, 40, 1, 5];
$count = count($arr);
for ($i=1; $i<$count; $i++) {
$preIndex = $i-1; // key 值 0
$current = $arr[$i]; // value 值 20
while ($preIndex>=0 && $arr[$preIndex] > $current) { // 如果 9 > 20 并且 key >= 0,则替换
$arr[$preIndex+1] = $arr[$preIndex]; // 替换值
$preIndex --;
}
$arr[$preIndex+1] = $current; // -1+1=0;
}
4. 希尔排序
是直接插入排序算法的一种更高效的改进版本,又称“缩小增量排序”
将要排序的数组按下标的一定增量进行分组,每组进行插入排序,随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个数组都被分成一组,算法结束。
$arr = [3,9,2,5,7,6,8,1];
$count = count($arr);
for ($gap = $count/2; $gap>0; $gap=$gap/2) { // 设置增量数 4,2,1
for ($i=$gap; $i<$count; $i++ ) { // 根据增量数进行循环
$j = $i
while ($j-$gap>=0 && $arr[$j]<$arr[$j-$gap]) { // 根据增量进行前后判断
$temp = $arr[$j]; // 位置切换
$arr[$j] = $arr[$j-$gap];
$arr[$j-$gap] = $temp;
$j -= $gap;
}
}
}
5. 快速排序
设置一个初始的中间值,来将需要排序的数组分成3部分。
小于中间值的放左边,中间值,大于中间值的放右边。使用递归用相同的方式来排序左边和右边,最后合并数组。
$arr = [3,9,2,5,7,6,8,1];
function quickSort($arr) {
$count = count($arr);
if($count>2) {
return $arr;
}
$leftArr = []; // 设置左右值
$rightArr = [];
$middle = $arr[0]; // 基准值,小->左边,大->右边
for ($i=1; $i<$count; $i++) { // 循环比较基准值
if ($midder < $arr[$i]) {
$rightArr[] = $arr[$i];
}else{
$leftArr[] = $arr[$i];
}
}
$rightArr = quickSort($rightArr); // 递归排序
$leftArr = quickSort($leftArr);
return array_merage($rightArr, $middle, $leftArr);
}
6. 计数排序
统计数组中每个元素出现的次数,对所有的计数累加
$arr = [3, 9, 2, 5, 7, 6, 8, 1, 1, 2, 5];
$maxValue = max($arr);
for ($m = 0; $m < $maxValue + 1; $m++) {
$bucket[] = null; // 设置空数组值
}
$arrLen = count($arr);
for ($i = 0; $i < $arrLen; $i++) {
if (!array_key_exists($arr[$i], $bucket)) {
$bucket[$arr[$i]] = 0;
}
$bucket[$arr[$i]]++;
}
$sortedIndex = 0;
foreach ($bucket as $key => $len) {
if ($len !== null) $arr[$sortedIndex++] = $key;
if($len !== null){
for($j = 0; $j < $len; $j++){
$arr[$sortedIndex++] = $key;
}
}
}
7. 二分查找
也称折半查找,它是一种效率较高的查找方法。
就是一分为二,然后两边比较,保留有效区间,继续一分为二查找,直到找到或者超出区间则结束
必须采用顺序存储结构,必须按关键字大小有序排列
设置 low = 0 、hight=10、mid=(low+hight) / 2 = 5,target = 52
比较中间元素 mid 和目标元素 target,如48小于52,则low=mid+1 = 6
此时 low = 6,hight = 10,min = 8
如没有相等,继续比较。69大于52,则high=mid-1 = 7
此时 low = 6,hight = 7,min = 6
///////////////////////////////////////////////////////////////
// 循环方式
function binary_search ($arr, $number) {
if (!in_array($arr, $number) || empty($number)) {
return '';
}
$count = count($arr);
$lower = 0; // 最小key
$hight = $count-1; // 最大key
whlie ($lower<=$hight) {
$middle = (($lower + $hight) / 2); // 中间key
if ($arr[$middle] < $number) { // 中间值与查找树比较,查找树大舍去左边。查找树小舍去右边
$lower = $middle + 1;
}else if($arr[$middle] > $number) {
$hight = $middle -1;
}else{
return $middle;
}
}
return '';
}
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$find_key = binary_search($arr, 7);
///////////////////////////////////////////////////////////////
// 递归方式
function binary_search_recursion($arr, $number, $lower, $higher) {
if ($lower > $higher) {
return -1;
}
$middle = intval(($lower+$higher) /2);
if ($number > $arr[$middle]) {
// 查找数比参照点大,舍去左边继续查找
return binary_search_recursion($arr, $number, $middle+1, $higher);
} elseif ($number < $arr[$middle]) {
return binary_search_recursion($arr, $number, $lower, $middle-1);
} else {
return $middle;
}
}
$arr = [1, 3, 7, 9, 11, 57, 63, 99];
binary_search_recursion($arr,11,0,count($arr));
8. 桶排序
桶排序是计数排序的升级版。它利用了函数的映射关系
在额外空间充足的情况下,尽量增大桶的数量
使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
$arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$min = min($arr);
$max = max($arr);
$bucket = array_fill($min, $max-$min+1, 0); // 生成桶,默认每个桶中数据只有0个
foreach ($nonSortArray as $value){
$bucket[$value]++; // 对应桶的个数计增
}
$sortArray = [];
foreach ($bucket as $k=>$v) {
for ($i=1; $i<=$v; $i++) { // 每个桶中的个数
$sortArray[]=$k;
}
}
return $sortArray;
9. 基数排序
基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较
由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数
$arr = [3, 9, 2, 5, 7, 6, 8, 1, 4, 90];
$arr_len = count($arr);
if ($arr_len<=1) {
return $arr;
}
$max = max($arr);
$max_len = strlen($max); // 获取最大的数的位数
$radix = 1; // 基数,从最后一位数开始
for ($i=0; $i < $max_len; $i++) { // 按最大位数读取各位的数
for ($j=0; $j < 10; $j++) {
$buckets[$j]=[]; // 用来装不同基数对应的值
}
foreach ($arr as $val) { // 按基数把数放到桶里
$buckets[($val/$radix)%10][]=$val;
}
$radix *= 10; // 基数进位
$k = 0;
$arr = [];
foreach ($buckets as $bucket) { // 把桶里的数重新存起来
foreach ($bucket as $val) {
$arr[$k++] = $val;
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律