算法是程序的核心,算法的好坏直接决定了程序的好坏
基础的几种算法
二分查找
冒泡排序
插入排序
选择排序
快速排序
二分查找
假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。(数据量大的时候使用)
//二分查找 function bin_search($arr,$low,$high,$k) { if($low <= $high) { $mid = intval(($low + $high)/2); if($arr[$mid] == $k) { return $mid; } else if($k < $arr[$mid]) { return bin_search($arr,$low,$mid-1,$k); } else { return bin_search($arr,$mid+1,$high,$k); } } return -1; } $arr = array(1,2,3,4,5,6,7,8,9,10); print(bin_search($arr,0,9,3));
冒泡排序:
效果图展示:(从小到大 and 从大到小 依次进行排序)
冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,依次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
步骤:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
实现原理:
38 49 65 97 76 13 27 比较第1个和第2个数,小的放前边,大的放后边 38 49 65 97 76 13 27 比较第2个和第3个数,小的放前边,大的放后边 38 49 65 97 76 13 27 比较第3个和第4个数,小的放前边,大的放后边 38 49 65 76 97 13 27 比较第4个和第5个数,小的放前边,大的放后边 38 49 65 76 13 97 27 比较第5个和第6个数,小的放前边,大的放后边 38 49 65 76 13 27 97 比较第6个和第7个数,小的放前边,大的放后边 至此,第一趟比较结束,得到以下排序: 38 49 65 76 13 27 97
代码:
//第一层可以理解为从数组中键为0开始循环到最后一个 $arr = [49,38,65,97,76,13,27]; for ($i=0;$i<count($arr);$i++){ for ($j=$i+1;$j<count($arr);$j++){//第二层为$i+1d的地方循环到数组最后 if ($arr[$i] < $arr[$j]){//比较数组中两个相邻值的大小 $temp = $arr[$i];//这里临时变量,存贮$i的值 $arr[$i] = $arr[$j];//第一次更换位置 $arr[$j] = $temp;//完成位置互换 } } } print_r($arr);
选择排序
选择排序(Selection sort)是一种简单直观的排序算法。
1.首先在未排序序列中找到最小元素,存放到排序序列的起始位置,
2.然后,再从剩余未排序元素中继续寻找最小元素,
3.然后放到排序序列末尾。
4.以此类推,直到所有元素均排序完毕。
$arr = [1, 43, 54, 62, 21, 66, 32, 78, 36, 76, 39, 2]; //选择排序 //实现思路 双重循环完成,外层控制轮数,当前的最小值。内层控制比较次数 function selectSort($arr) { $len = count($arr); //$i 当前最小值的位置, 需要参与比较的元素 for ($i = 0; $i < $len - 1; $i++) { //先假设最小的值的位置 $p = $i; //$j 当前都需要和哪些元素比较,$i 后边的。 for ($j = $i + 1; $j < $len; $j++) { //$arr[$p] 是 当前已知的最小值 //比较,发现更小的,记录下最小值的位置;并且在下次比较时,应该采用已知的最小值进行比较。 $p = ($arr[$p] <= $arr[$j]) ? $p : $j; } //已经确定了当前的最小值的位置,保存到$p中。 //如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可 if ($p != $i) { $tmp = $arr[$p]; $arr[$p] = $arr[$i]; $arr[$i] = $tmp; } } //返回最终结果 return $arr; } $arr = selectSort($arr); print_r($arr);
插入排序
插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
步骤:
1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果该元素(已排序)大于新元素,将该元素移到下一位置
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5.将新元素插入到该位置中
6.重复步骤2
$arr = [1, 43, 54, 62, 21, 66, 32, 78, 36, 76, 39,2]; //插入排序 function insert_sort($arr) { $len=count($arr); for($i=1; $i<$len; $i++) { //获得当前需要比较的元素值 $tmp = $arr[$i]; //内层循环控制 比较 并 插入 for($j=$i-1; $j>=0; $j--) { //$arr[$i];需要插入的元素 //$arr[$j];需要比较的元素 if($tmp < $arr[$j]) //从小到大 < || 从大到小 > { //发现插入的元素要小,交换位置 //将后边的元素与前面的元素互换 $arr[$j+1] = $arr[$j]; //将前面的数设置为 当前需要交换的数 $arr[$j] = $tmp; } else { //如果碰到不需要移动的元素 //由于是已经排序好是数组,则前面的就不需要再次比较了。 break; } } } //将这个元素 插入到已经排序好的序列内。 //返回 return $arr; } $arr = insert_sort($arr); print_r($arr);
快速排序
快速排序是由东尼·霍尔所发展的一种排序算法。
在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。
事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性。
步骤:
1.从数列中挑出一个元素,称为 “基准”(pivot),
2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
<?php $arr = [1, 43, 54, 62, 21, 66, 32, 78, 36, 76, 39,2]; //快速排序 function quick_sort($arr) { //判断参数是否是一个数组 if(!is_array($arr)) return false; //递归出口:数组长度为1,直接返回数组 $length = count($arr); if($length<=1) return $arr; //数组元素有多个,则定义两个空数组 $left = $right = array(); //使用for循环进行遍历,把第一个元素当做比较的对象 for($i=1; $i<$length; $i++) { //判断当前元素的大小 if($arr[$i] < $arr[0]){ //从小到大 < || 从大到小 > $left[]=$arr[$i]; }else{ $right[]=$arr[$i]; } } //递归调用 $left=quick_sort($left); $right=quick_sort($right); //将所有的结果合并 return array_merge($left,array($arr[0]),$right); } $arr = quick_sort($arr); print_r($arr);
归并排序
利用递归,先拆分、后合并、再排序。
步骤:
均分数列为两个子数列
递归重复上一步骤,直到子数列只有一个元素
父数列合并两个子数列并排序,递归返回数列
数据结构
spl,指SPL - Standard PHP Library 标准PHP类库。
双向链表
双链表 (DLL) 是一个链接到两个方向的节点列表。当底层结构是 DLL 时, 迭代器的操作、对两端的访问、节点的添加或删除都具有 O (1) 的开销。因此, 它为栈和队列提供了一个合适的实现。
SplDoublyLinkedList
SplStack
SplQueue
堆
堆是遵循堆属性的树状结构: 每个节点都大于或等于其子级, 使用对堆全局的已实现的比较方法进行比较。
SplHeap
SplMaxHeap
SplMinHeap
SplPriorityQueue
数组
数组是以连续方式存储数据的结构, 可通过索引进行访问。不要将它们与 php 数组混淆: php 数组实际上是按照有序的列表实现的。
SplFixedArray
映射
映射是一个数据拥有键值对。PHP 数组可以被看作是从整数/字符串到值的映射。SPL 提供了从对象到数据的映射。此映射也可用作对象集。
SplObjectStorage
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!