PHP常用(数组)算法 -(冒泡排序)-(归并排序)-(二分查找-递归)-(二分查找-非递归)-(选择排序)-(插入排序)
冒泡排序 /* * Notes: 冒泡排序,依次比较两个数进行排序,顺序(小数往前放,大数往后放),逆序(大数往前放,小数往后放) * @param: $arr 待排序数组 * return 已排好序的数组 */ function bubbleSort($arr) { $n = count($arr); //循环数组,从数组第一个值到数组的倒数第二个值 for ($i = 0; $i < $n - 1; $i++) { //循环数组,从数组第二个值到数组的最后一个值 for ($j = $i + 1; $j < $n; $j++) { //将两数进行比较 如果后面一个数比前面数小,则往前放(如果需要逆序,则可以写成后面一个数比前面一个数大往前放) if ($arr[$j] < $arr[$i]) { $temp = $arr[$i]; $arr[$i] = $arr[$j]; $arr[$j] = $temp; } } } return $arr; } 归并排序 /* * Notes: 归并排序, * @param: $arr 待排序数组 */ function MergeSort(&$arr) { $start = 0; //数组第一个数键值 $end = count($arr) - 1; //数组最后一个数键值 MSort($arr, $start, $end); } function MSort(&$arr, $start, $end) { //当子序列长度为1时,$start == $end,不用再分组 if ($start < $end) { $mid = floor(($start + $end) / 2); //将 $arr 平分为 $arr[$start - $mid] 和 $arr[$mid+1 - $end] MSort($arr, $start, $mid); //将 $arr[$start - $mid] 归并为有序的$arr[$start - $mid] MSort($arr, $mid + 1, $end); //将 $arr[$mid+1 - $end] 归并为有序的 $arr[$mid+1 - $end] Merge($arr, $start, $mid, $end); //将$arr[$start - $mid]部分和$arr[$mid+1 - $end]部分合并起来成为有序的$arr[$start - $end] } } function Merge(array &$arr, $start, $mid, $end) { $i = $start; $j = $mid + 1; $k = $start; $temparr = array(); while ($i != $mid + 1 && $j != $end + 1) { if ($arr[$i] >= $arr[$j]) { $temparr[$k++] = $arr[$j++]; } else { $temparr[$k++] = $arr[$i++]; } } //将第一个子序列的剩余部分添加到已经排好序的 $temparr 数组中 while ($i != $mid + 1) { $temparr[$k++] = $arr[$i++]; } //将第二个子序列的剩余部分添加到已经排好序的 $temparr 数组中 while ($j != $end + 1) { $temparr[$k++] = $arr[$j++]; } for ($i = $start; $i <= $end; $i++) { $arr[$i] = $temparr[$i]; } } 二分查找-递归 /* * Notes: 二分查找(递归),先取数组中间数进行比较,若查找数值比这个数小,则往前查,否则往后查 * @param: $arr 已经排好序的数组 * @param: $low 首位置 * @param: $high 尾位置 * @param: $value 需要查找的数 * return 查到的数组中的键值,未查到则返回false */ function binSearch($arr, $low, $high, $value) { if ($low <= $high) { //当首位置大于尾位置时,返回false //取中间值 $mid = floor(($low + $high) / 2); if ($value == $arr[$mid]) { //当需要查找的数值与数组中的数值相等时,则返回键值 return $mid; } elseif ($value < $arr[$mid]) { //当需要查找的数值小于数组中的数组时,尾位置值-1,回调 return binSearch($arr, $low, $mid - 1, $value); } else { //其余的则首位置+1,回调 return binSearch($arr, $mid + 1, $high, $value); } } return false; } 二分查找-非递归 /* * Notes: 二分查找(非递归),先取数组中间数进行比较,若查找数值比这个数小,则往前查,否则往后查 * @param: $arr 已经排好序的数组 * @param: $low 首位置 * @param: $high 尾位置 * @param: $value 需要查找的数 * return 查到的数组中的键值,未查到则返回false */ function binSearch($arr, $low, $high, $value) { //判断当首位置值小于等于尾位置值 while($low <= $high) { //取中间值 $mid = floor(($low + $high) / 2); if($value == $arr[$mid]) { //当需要查找的数值与数组中的数值相等时,则返回键值 return $mid; } elseif ($value < $arr[$mid]) { //当需要查找的数值小于数组中的数组时,尾位置值-1 $high = $mid - 1; } else { //其余的则首位置+1 $low = $mid + 1; } } return false; } 快速排序 /* * Notes: 快速排序 * @param: $arr 未做排序的数组 * return 返回已排好序的数组 */ function quickSort($arr) { $n = count($arr); //如果数组长度小于等于1,直接返回数组 if ($n <= 1) { return $arr; } //首先拿数组第一个(在数组中键值为0)值做为中间值 $key = $arr[0]; //初始化两个数组,用于接收小于中间值和大于中间值的数据 $left_arr = array(); $right_arr = array(); //从数组第二个数开始循环(在数组中键值为1)进行判断比较 for ($i = 1; $i < $n; $i++) { if ($arr[$i] <= $key) { //数值小于中间值时,将数值放入左侧数组中 $left_arr[] = $arr[$i]; } else { //数值大于中间值时,将数值放入右侧数组中 $right_arr[] = $arr[$i]; } } //递归排序划分好的2边 $left_arr = quick_sort($left_arr); $right_arr = quick_sort($right_arr); //合并数组 return array_merge($left_arr, array($key), $right_arr); } 选择排序 /* * Notes: 选择排序,从第一个数开始,拿后面的数跟它进行比较,如果比它小则两个数交换位置,以此类推,一直到最后一个数 * @param: $arr array 未排序的数组 * return $arr array 已排序的数组 */ function selectSort($arr) { //循环数组,从第一个开始 for ($i = 0; $i < count($arr); $i++) { $k = $i; //从后面一个数开始,跟拿出来的数进行比较 for ($j = $i + 1; $j < count($arr); $j++) { //如果后面的数小于前面的数,则拿小的那个数的key if ($arr[$j] < $arr[$k]) { $k = $j; } } //如果有数比前面的小,则进行数据交换 if ($k != $i) { $temp = $arr[$i]; $arr[$i] = $arr[$k]; $arr[$k] = $temp; } } //返回已排好序的数组 return $arr; } 插入排序 /* * Notes: 插入排序分两块,已排序块与未排序块,每次从未排序块拿出一个数,跟已排序块的数据进行比较,进行数据的插入 * @param $arr array 未排序的数组 * return $arr array 已排序的数组 */ function insertSort($arr) { //循环数组,从第二个开始,默认第一个为已排序区 for ($i = 1; $i < count($arr); $i++) { //取一个数 $tmp = $arr[$i]; $j = $i - 1; //将取出的数依次跟已排序区的数进行比较(这边的排序是从小到大的排序,如果需要倒叙,则<即可) while ($arr[j] > $tmp) { //若条件成立,则进行数据的插入 $arr[$j + 1] = $arr[$j]; $arr[$j] = $tmp; $j--; //若已经读已排序区的所有数进行了比较插入,则结束此数的比较,插入完成,进行下一个数的比较插入 if ($j < 0) { break; } } } //返回已排好序的数组 return $arr; }