Loading... ## 排序 ### 冒泡排序 依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面。 ```php $arr = [8,1,10,9,5,7]; function bubbleSort($arr){ // 外层 for 循环控制循环次数 for ($i=0; $i<count($arr) ; $i++) { //内层 for 循环进行两数交换,找每次的最大数,排到最后 for ($j=0; $j < count($arr)-1; $j++) { //数组里第一个和第二个对比,如果1>2,执行数值互换 if($arr[$j] >$arr[$j+1]){ $x = $arr[$j]; //第一赋给一个变量 $arr[$j] = $arr[$j+1]; //第二赋给第一 $arr[$j+1] = $x; //把变量给第二,结果就是1,2的数值互换 // $a=10; // $b=20; // $x=$a; $x=10 // $a=$b; $a=20 // $b=$X; $b=10 } } } return $arr; } print_r(bubbleSort($arr)); ``` ### 快速排序 快速排序是对冒泡排序的一种改进。 设置一个基准元素,通过排序将需要排序的数据分割成两个部分,其中一部分的所有数据比基准元素小,另一部分的所有数据比基准元素大,然后对这两部分数据分别进行递归快速排序,最后将得到的数据和基准元素进行合并,就得到了所需数据。 ```php $arr = [8,1,10,9,5,7]; function quickSort($arr){ $lenth = count($arr);//获取数组个数 if($lenth <= 1){//小于等于一个不用往下走了 return $arr; } //选择基准元素。一般选第一个或最后一个 $first = $arr[0]; $left = array();//接收小于基准元素的值 $right = array();//接收大于基准元素的值 //循环从1开始,因为基准元素是0 for($i=1;$i<$lenth;$i++){ if($arr[$i]<$first){//小于基准元素的值 $left[] = $arr[$i]; }else{//大于基准元素的值 $right[] = $arr[$i]; } } //递归排序 $left = quickSort($left); $right = quickSort($right); //合并返回数组 return array_merge($left,array($first),$right); } print_r(quickSort($arr)); ``` ### 选择排序 1.找到数组中最小的元素,拎出来,将它和数组的第一个元素交换位置; 2.在剩下的元素中继续寻找最小的元素,拎出来,和数组的第二个元素交换位置; 3.如此循环,直到整个数组排序完成。 ```php $arr = [8,1,10,9,5,7]; function selectSort($arr){ //实现思路 双重循环完成,外层控制轮数,当前的最小值。内层 控制的比较次数,$i 当前最小值的位置, 需要参与比较的元素 for($i=0, $len=count($arr); $i<$len-1; $i++){ //先假设最小的值的位置 $p = $i; //$j 当前都需要和哪些元素比较,$i 后边的。 for($j=$i+1; $j<$len; $j++) { //$arr[$p] 是 当前已知的最小值 if($arr[$p] > $arr[$j]){ //比较,发现更小的,记录下最小值的位置;并且在下次比较时,应该采用已知的最小值进行比较。 $p = $j; } } //已经确定了当前的最小值的位置,保存到$p中。如果发现 最小值的位置与当前假设的位置$i不同,则位置互换即可。 if($p != $i){ $tmp = $arr[$p]; $arr[$p] = $arr[$i]; $arr[$i] = $tmp; } } return $arr; } print_r(selectSort($arr)); ``` ### 插入排序 每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。 ```php $arr = [8,1,10,9,5,7]; function insertSort($arr){ $count = count($arr); for($i=1; $i<$count; $i++){ $tmp = $arr[$i]; $j = $i - 1; while(isset($arr[$j]) && $arr[$j] > $tmp){ $arr[$j+1] = $arr[$j]; $arr[$j] = $tmp; $j--; } } return $arr; } print_r(insertSort($arr)); ``` ### 希尔排序 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。 希尔排序实质上是一种分组插入方法。它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中;然后,对各组内的元素进行直接插入排序。 这一趟排序完成之后,每一个组的元素都是有序的。然后减小gap的值,并重复执行上述的分组和排序。重复这样的操作,当gap=1时,整个数列就是有序的。 ```php $arr = [8,1,10,9,5,7]; function shellSort(&$arr){ if(!is_array($arr))return;$n=count($arr); for($gap=floor($n/2);$gap>0;$gap=floor($gap/=2)){ for($i=$gap;$i<$n;++$i){ for($j=$i-$gap;$j>=0&&$arr[$j+$gap]<$arr[$j];$j-=$gap){ $temp=$arr[$j]; $arr[$j]=$arr[$j+$gap]; $arr[$j+$gap]=$temp; } } } return $arr; } print_r(shellSort($arr)); ``` ## 查找 ### 二分查找 二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。 首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。 ```php /** * 二分查找(Binary Search)算法,也叫折半查找算法。二分查找的思想非常简单,有点类似分治的思想。 * 二分查找针对的是一个有序的数据集合,每次都通过跟区间的中间元素对比, * 将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。 * * 循环写法 * @param array $array 待查找的数组 * @param int $findVal 要查找的值 * @return int 返回找到的数组键 */ function binarySearch($array, $findVal) { // 非数组或者数组为空,直接返回-1 if (!is_array($array) || empty($array)) { return -1; } // 查找区间,起点和终点 $start = 0; $end = count($array) - 1; while ($start <= $end) { // 以中间点作为参照点比较,取整数 $middle = intval(($start + $end) / 2); if ($array[$middle] > $findVal) { // 查找数比参照点小,则要查找的数在左半边 // 因为 $middle 已经比较过了,这里需要减1 $end = $middle - 1; } elseif ($array[$middle] < $findVal) { // 查找数比参照点大,则要查找的数在右半边 // 因为 $middle 已经比较过了,这里需要加1 $start = $middle + 1; } else { // 查找数与参照点相等,则找到返回 return $middle; } } // 未找到,返回-1 return -1; } // 调用 $array = [10,12,16,19,20,34,56,78,84,95,100]; echo binarySearch($array, 84); /** * 递归写法 * @param array $array 待查找的数组 * @param int $findVal 要查找的值 * @param int $start 查找区间,起点 * @param int $end 查找区间,终点 * @return int 返回找到的数组键 */ function binSearch($array, $findVal, $start, $end) { // 以中间点作为参照点比较,取整数 $middle = intval(($start + $end) / 2); if ($start > $end) { return -1; } if ($findVal > $array[$middle]) { // 查找数比参照点大,则要查找的数在右半边 return binSearch($array, $findVal, $middle + 1, $end); } elseif ($findVal < $array[$middle]) { // 查找数比参照点小,则要查找的数在左半边 return binSearch($array, $findVal, $start, $middle - 1); } else { return $middle; } } // 调用 $arr = [10,12,16,19,20,34,56,78,84,95,100]; var_dump(binSearch($arr, 95, 0, count($arr)-1)); ``` 最后修改:2023 年 09 月 05 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏