用php实现四种常见的排序算法
几种常见的排序
排序是一个程序员的基本功,对于初级phper,更是可以通过排序算法来锻炼自己的思维能力。
所谓排序,就是对一组数据,按照某个顺序排列的过程。下面就总结四种常用的php排序算法,分别是冒泡排序,选择排序,插入排序以及快速排序。
一,冒泡排序(Bubble sort)
在几种排序中,个人认为冒泡排序相对而言是比较简单也是非常常用的一种排序方法。
基本思想:如下图所示,将一组数据看作一排竖着的气泡,然后让最后一个数与倒数第二个数进行比较,大的就往前移。然后用相同的方法,将倒数第二个数与倒数第三个进行比较,大的往前移,依次类推,最后本轮循环结束后,第一个元素就是最大的了,然后继续循环,得到第二个,第三个……
下面给出实现代码,已经优化过的冒泡排序
1 function BubbleSort(&$arr){ //必须是&$arr,传一个地址,如果是$arr,根据函数调用机制,排序将无法生效 2 $temp=0; //中间变量 3 $flag=false; 4 //外层循环控制循环次数 5 for($i=0;$i<count($arr)-1;$i++){ 6 //内层循环控制每一次循环的交换 7 for($j=0;$j<count($arr)-1-$i;$j++){ 8 //若前面的数比后面的数大,则交换 9 if($arr[$j]>$arr[$j+1]){ 10 $temp=$arr[$j]; 11 $arr[$j]=$arr[$j+1]; 12 $arr[$j+1]=$temp; 13 $flag=true; 14 } 15 } 16 if(!$flag){ 17 //已经是有序 18 break; 19 20 } 21 $flag=false; 22 } 23 return $arr; 24 }
细心的人就会发现,我在程序中定义了一个$flag变量,主要是用来判断数据是否已经有序,从而优化了冒泡排序算法。
二,选择排序(Selection sort)
首先,拿第一个和后面所有的比,找出最小的那个数字,然后和第一个数互换(当然,如果是第一个最小,那么就不用互换了),接着循环,即:拿第二个和后面的比较,找出最小的数字,然后和第二个数字互换,依次类推,也就是说每次都是找出剩余最小的值。
代码如下:
function selectSort(&$arr){ $temp=0; //中间变量 //外层循环 for($i=0;$i<count($arr)-1;$i++){ //假设第$i个数就是最小的数 //记录假设的最小数的值 $minVal=$arr[$i]; //记录假设的最小数的下标 $minIndex=$i; for($j=$i+1;$j<count($arr);$j++){ //如果假设的最小值,不是最小 if($minVal>$arr[$j]){ $minVal=$arr[$j]; $minIndex=$j; } } //最后交换 $temp=$arr[$i]; $arr[$i]=$arr[$minIndex]; //循环外面,不能出现$j $arr[$minIndex]=$temp; } return $arr; }
三 , 插入排序(Insert sort)
插入排序的基本思想是:在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。如下图所示:
下面贴出代码
1 function insertSort(&$arr){ 2 //默认第一个数,即下标为0的数,已经是有序 3 for($i=1;$i<count($arr);$i++){ 4 //准备插入的数 5 $insertVal=$arr[$i]; 6 //准备先和$insertIndex比较 7 $insertIndex=$i-1; 8 while($insertIndex>=0&&$insertVal<$arr[$insertIndex]){ 9 $arr[$insertIndex+1]=$arr[$insertIndex]; 10 $insertIndex--; 11 } 12 $arr[$insertIndex+1]=$insertVal; 13 } 14 return $arr; 15 }
四, 快速排序
基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素。通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
function quickSort(&$arr) { //先判断是否需要继续进行 $length = count($arr); if($length <= 1) { return $arr; } //选择第一个元素作为基准 $base_num = $arr[0]; //遍历除了标尺外的所有元素,按照大小关系放入两个数组内 //初始化两个数组 $left_array = array(); //小于基准的 $right_array = array(); //大于基准的 for($i=1; $i<$length; $i++) { if($base_num > $arr[$i]) { //放入左边数组 $left_array[] = $arr[$i]; } else { //放入右边 $right_array[] = $arr[$i]; } } //再分别对左边和右边的数组进行相同的排序处理方式递归调用这个函数 $left_array = quickSort($left_array); $right_array = quickSort($right_array); //合并 return array_merge($left_array, array($base_num), $right_array); }