当前位置: 首页 > 后端技术 > PHP

PHP算法之四大基本算法

时间:2023-03-29 22:42:13 PHP

前言虽然你在工作中感觉自己没有涉及到算法,但是算法才是程序的核心。一个程序好坏的关键在于程序算法的优劣,所以对于冒泡排序、插入排序、选择排序、快速排序这四种基本算法,我觉得还是需要掌握的。冒泡排序冒泡排序大致的意思是依次比较相邻的两个数,然后按大小排序,直到最后两位。因为在排序过程中,总是小数点往前,大数往后放,相当于冒泡上升,所以叫冒泡排序。气泡从前到后出现,所以每一轮的比较次数逐渐减少。最后一个数不需要比较,时间复杂度为O(n2)。算法如下:/***冒泡排序算法*@paramarray$arr*@returnarray*/functionbubble_sort($arr){//判断参数是否为数组且不为空if(!is_array($arr)||empty($arr)){返回$arr;}//循环需要冒泡的轮数for($i=1,$len=count($arr);$i<$len;$i++){//每轮需要比较的次数循环for($j=0;$j<$len-$i;$j++){//大数,交换位置,向后移动if($arr[$j]>$arr[$j+1]){$temp=$arr[$j+1];$arr[$j+1]=$arr[$j];$arr[$j]=$temp;}}}return$arr;}选择排序选择排序原理:先在未排序的序列中找到最小(最大)的元素,存入已排序序列的开头,然后继续从中寻找最小(最大)的元素剩余的未排序元素,放在已排序序列的末尾;依此类推,直到所有元素都排序完毕。选择是每次假设一个最小值的位置,然后依次将假设的最小值和后面的值进行比较,找出实际的最小值放在假设最小值的位置,其时间复杂度为也是O(n2),算法如下:/***选择排序方法*@paramarray$arr*@returnarray*/functionselect_sort($arr){//判断参数是否为数组且不为空如果(!is_array($arr)||empty($arr)){返回$arr;}$len=count($arr);for($i=0;$i<$len-1;$i++){//假设最小数的位置$min=$i;//循环比较假设的最小数和$i之后的数,找出实际的最小数for($j=$i+1;$j<$len;$j++){//比假设的最小数更小的数数,替换最小数if($arr[$min]>$arr[$j]){$min=$j;}}//假定的最小数与实际数不符,交换位置if($min!=$i){$temp=$arr[$min];$arr[$min]=$arr[$i];$arr[$i]=$temp;}}return$arr;}插入排序插入排序法的原理:每次将一条待排序的记录按照其key大小插入到之前排序好的子序列中的合适位置,直到所有记录都被插入。插入排序方法是先对已排序元素的前两个元素进行排序,然后将第三个元素插入到已经排好序的两个元素中,所以这三个元素还是按照从小到大排序,再插入第四个元素,重复操作,直到所有元素都排序完毕;它的时间复杂度也是O(n2),算法如下:/***插入排序法*@paramarray$arr*@returnarray*/functioninsert_sort($arr){//判断参数是否为一个数组且不为空if(!is_array($arr)||empty($arr)){return$arr;}$len=count($arr);for($i=1;$i<$len;$i++){//当前要比较的临时数$tmp=$arr[$i];//循环比较临时数前的数for($j=$i-1;$j>=0;$j--){//前一个数大于临时数,则交换位置if($arr[$j]>$tmp){$arr[$j+1]=$arr[$j];$arr[$j]=$tmp;}}}return$arr;}快速排序快速排序是对冒泡排序的改进。他的基本原理是:通过one-pass排序将待排序的记录分成独立的两部分,其中一部分记录的关键词小于另一部分记录的关键词,那么这两部分记录就可以分别进行快速排序,而整个排序过程可以递归进行,从而达到对整个序列进行排序的目的。快速排序法是从数列中挑出第一个数(最后一个数)作为参考元素,然后循环遍历所有的数,并与参考书进行比较并分成左右两列,然后重复这一步继续将它们分成左右两列。算法如下:/***快速排序方法*@paramarray$arr*@returnarray*/functionquick_sort($arr){//判断参数是否为数组且不为空if(!is_array($arr)||empty($arr)){返回$arr;}//数组长度为1停止排序$len=count($arr);如果($len==1){返回$arr;}//声明左右空数组$left=$right=[];//循环遍历,取第一个元素作为参考数for($i=1;$i<$len;$i++){//比较当前数的大小,将对应的左右数组放入if($arr[$i]>$arr[0]){$right[]=$arr[$i];}else{$left[]=$arr[$i];}}//递归比较$left=quick_sort($left);$right=quick_sort($right);//合并左右列和引用数获取返回的排序数组;说明一下,我这里的排序设计是递增的,如果需要递减,需要修改排序算法字符的比较和替换即可。//待排序数组$arr=[1,4,5,9,3,8,6];//调用排序方法$sort_arr=bubble_sort($arr);//输出printprint_r($sort_arr);分析算法通常,对于一个给定的算法,我们要做两个分析:首先是从数学上证明算法的正确性。这一步主要使用形式化证明方法和相关的推理模式,如循环不变量、数学归纳等。在证明算法正确的基础上,第二步分析算法的时间复杂度。一个算法的时间复杂度反映了程序执行时间随着输入规模的增加而增加的幅度,可以在很大程度上反映算法的优劣。而我们通常所说的:算法优化无非是以时间换空间,以空间换时间。一般来说,两者不能结合。结论要实现一个程序,必须有多种算法。如果还有什么想说的,可以留言和我交流,谢谢!如有问题请指出,我会及时改正,谢谢!