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 }