PHP 常用排序算法

  1 <?php
  2 
  3 class Sort {
  4     /**
  5      * 交换数组中的元素
  6      * @param $input
  7      * @param $i
  8      * @param $j
  9      */
 10     protected static function swap(&$input, $i, $j)
 11     {
 12         $tmp = $input[$i];
 13         $input[$i] = $input[$j];
 14         $input[$j] = $tmp;
 15     }
 16 
 17     /**
 18      * 冒泡排序
 19      * @param ...$values
 20      * @return array
 21      */
 22     public static function buffsort_v1(...$values){
 23         $len = count($values);
 24         for($i = 0; $i < $len - 1; $i++){
 25             //内层循环,当前元素与下一个元素比较,然后交换。再重复,这种相邻比较,最小的元素就移动到最后的位置了,重复轮都将最小值移动到指定位置。
 26             for($j = 0; $j < $len - 1 - $i; $j++){
 27                 if($values[$j] < $values[$j + 1]) continue;
 28                 $temp = $values[$j];
 29                 $values[$j] = $values[$j + 1];
 30                 $values[$j + 1] = $temp;
 31             }
 32         }
 33         return $values;
 34 
 35     }
 36 
 37     /**
 38      * 冒泡排序
 39      * @param $input
 40      * @return array
 41      */
 42     public static function buffsort_v2($input)
 43     {
 44         if (!is_array($input)) {
 45             $input = func_get_args();
 46         }
 47         if (empty($input)) {
 48             return $input;
 49         }
 50 
 51         $length = count($input);
 52         for ($i = 0; $i < $length - 1; $i++) {
 53             $swaped = false; //用于判断一轮比较是否发生过交换,如果没有,表示排序完成
 54 
 55             //从后面往前比较,每轮都排序好一个元素,因此必须 $j>$i
 56             for ($j = $length - 1; $j > $i; $j--) {
 57                 if ($input[$j] > $input[$j - 1]) {
 58                     $swaped = true;
 59                     self::swap($input, $j, $j - 1);
 60                 }
 61             }
 62             if (!$swaped) {
 63                 break;
 64             }
 65         }
 66         return $input;
 67     }
 68 
 69 
 70 
 71     /**
 72      * 选择排序法: 每次从数组中找到一个最值,放在相应位置
 73      * O(n^2)
 74      */
 75     public static function select($input)
 76     {
 77         if (!is_array($input)) {
 78             $input = func_get_args();
 79         }
 80         if (empty($input)) {
 81             return $input;
 82         }
 83 
 84         $length = count($input);
 85         for ($i = 0; $i < $length - 1; $i++) {
 86             $max = $i;
 87             //从 i+1 开始比较,因为 max 默认为i了,i就没必要比了
 88             for ($j = $i + 1; $j < $length; $j++) {
 89                 if ($input[$max] < $input[$j]) {
 90                     $max = $j;
 91                 }
 92             }
 93             //如果 max 不为 i,说明找到了更大的值,则交换
 94             if ($max != $i) {
 95                 self::swap($input, $i, $max);
 96             }
 97         }
 98 
 99         return $input;
100     }
101 
102     /**
103      * 插入排序法:从第二个元素开始比较,然后放到相应的位置,就想打牌一样.
104      * @param $input
105      * @return array
106      */
107     public static function insert($input)
108     {
109         if (!is_array($input)) {
110             $input = func_get_args();
111         }
112         if (empty($input)) {
113             return $input;
114         }
115 
116         $length = count($input);
117         //从第二个元素开始比较,然后放到相应的位置
118         for ($i = 1; $i < $length; $i++) {
119 
120             //j与它前面的元素相比,所以每一轮要比较的个数会越来越多
121             for ($j = $i; $j > 0; $j--) {
122                 if ($input[$j - 1] < $input[$j]) {
123                     self::swap($input, $j, $j - 1);
124                 } else {
125                     break;
126                 }
127             }
128         }
129 
130         return $input;
131     }
132 
133 
134     /**
135      * 快速排序法
136      * @param $input
137      * @return array
138      */
139     public static function quick($input)
140     {
141         if (!is_array($input)) {
142             $input = func_get_args();
143         }
144 
145         //先判断是否需要继续进行
146         $length = count($input);
147         if ($length <= 1) {
148             return $input;
149         }
150 
151         $base = $input[0]; //选择第一个元素作为基准
152 
153         //初始化两个数组
154         $left = $right = array();
155         for ($i = 1; $i < $length; $i++) {
156             if ($base > $input[$i]) {
157                 $left[] = $input[$i]; //小的放入左边
158             } else {
159                 $right[] = $input[$i];//大的放入右边
160             }
161         }
162 
163         //分段之后分别递归调用
164         $left = self::quick($left);
165         $right = self::quick($right);
166 
167         return array_merge($left, array($base), $right);
168     }
169     
170 }

 

posted @ 2023-05-26 14:48  心随所遇  阅读(6)  评论(0编辑  收藏  举报