跳到主要内容

排序算法

冒泡排序

冒泡排序-Gist

每一轮遍历一遍列表,比较两个相邻的元素,将值大的元素交换至右端。

/**
* 冒泡排序(从小到大)
* ```说明
* 对于一个长度为N的数组,我们需要排序 N-1 轮,每 i 轮 要比较 N-i 次。
* 对此我们可以用双重循环语句,外层循环控制循环轮次,内层循环控制每轮的比较次数。
* - 方式1
* $count - 1 - $i,最后一个数为最大,所以内层每轮少比较一次。
* - 方式2
* $count - 1,每轮都比较 n-1 次。
* ```
* @param array $array
* @return array
*/
function bubbleSort($array = []) {
$count = count($array);
for ($i = 0; $i < $count - 1; $i++) {
for ($j = 0; $j < $count - 1 - $i; $j++) {
// 比较相邻的两个数,如果左边 > 右边,则交换位置。
if ($array[$j] > $array[$j + 1]) {
$temp = $array[$j];
$array[$j] = $array[$j + 1];
$array[$j + 1] = $temp;
}
}
}
return $array;
}

插入排序

插入排序-Gist

插入排序基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。 插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

/**
* 插入排序(从小到大)
* @param array $array
* @return array
*/
function insertSort($array = []) {
$count = count($array);
for ($i = 1; $i < $count; $i++) {
// 获得当前需要比较的元素值
$temp = $array[$i];
// 内层循环控制 比较并插入
for ($j = $i - 1; $j >= 0; $j--) {
// $array[$i] 需要插入的元素,$array[$j] 需要比较的元素。
if ($temp < $array[$j]) {
// 发现插入的元素要小,交换位置,将后边的元素与前面的元素互换。
$array[$j + 1] = $array[$j];
// 将前面的数设置为 当前需要交换的数
$array[$j] = $temp;
} else {
// 如果碰到不需要移动的元素,由于是已经排序好的数组,则前面的就不需要再次比较了。
break;
}
}
}
return $array;
}

快速排序

快速排序-Gist

找到当前数组中的任意一个元素(一般选择第一个元素)为 "中间值",声明两个空数组 "左边和右边"。 遍历整个数组元素,如果遍历到的元素大于中间值则放到 "右边",小于中间值则放到 "左边",然后再对新数组进行同样的操作, 最后将 "左边和中间值、右边" 合并。

/**
* 快速排序(从小到大)
* @param array $array
* @return array
*/
function quickSort($array = []) {
$count = count($array);
if ($count <= 1) {
return $array;
}
$key = $array[0];
$rightArray = [];
$leftArray = [];
for ($i = 1; $i < $count; $i++) {
if ($array[$i] >= $key) {
$rightArray[] = $array[$i];
} else {
$leftArray[] = $array[$i];
}
}
$leftArray = quickSort($leftArray);
$rightArray = quickSort($rightArray);
$mergeArray = array_merge($leftArray, array($key), $rightArray);
return $mergeArray;
}

选择排序

选择排序-Gist

就是在第一次循环中,假设第一个数是最小的,然后跟第二个数比较,一直比到最后, 找出最小值,然后把最小值跟第一个数的位置互换;再进行下一次循环,找出最小值跟第二个位置的数互换, 一直循环数组的个数减去1次,数组就成了有序的了

/**
* 选择排序(从小到大)
* @param array $array
* @return array
*/
function selectSort($array = []) {
// 双重循环完成,外层控制轮数,内层控制比较次数。
$count = count($array);
for ($i = 0; $i < $count - 1; $i++) {
// 先假设最小的值的位置
$p = $i;
// $j 当前都需要和哪些元素比较,$i 后边的。
for ($j = $i + 1; $j < $count; $j++) {
// 发现更小的值,记录下最小值的位置;并且在下次比较时采用已知的最小值进行比较。
if ($array[$p] > $array[$j]) {
$p = $j;
}
}
// 已经确定了当前的最小值的位置,保存到 $p 中,如果发现最小值的位置与当前假设的位置 $i 不同,则互换位置。
if ($p != $i) {
$temp = $array[$p];
$array[$p] = $array[$i];
$array[$i] = $temp;
}
}
return $array;
}