/**修改版冒泡排序法
*/
function bubbleSort(&$arr) :void
{
$swapped = false;
$bound = count($arr) - 1;
for ($i = 0, $c = count($arr); $i < $c; $i++) {
for ($j = 0; $j < $bound; $j++) {
if ($arr[$j + 1] < $arr[$j]) {
list($arr[$j], $arr[$j + 1]) = array($arr[$j + 1], $arr[$j]);
//list()在PHP5和PHP7的效果不一样
$swapped = true;
$newBound = $j;
}
}
$bound = $newBound;
if (!$swapped) break; //没有发生交换,算法结束
}
}
/*
选择排序每次找到最小(最大)的与之互换位置
*/
function selectionSort(&$arr)
{
$count = count($arr);
//重复元素个数-1次
for ($j = 0; $j <= $count - 1; $j++) {
//把第一个没有排过序的元素设置为最小值
$min = $arr[$j];
//遍历每一个没有排过序的元素
for ($i = $j + 1; $i < $count; $i++) {
//如果这个值小于最小值
if ($arr[$i] < $min) {
//把这个元素设置为最小值
$min = $arr[$i];
//把最小值的位置设置为这个元素的位置
$minPos = $i;
}
}
//内循环结束把最小值和没有排过序的元素交换
list($arr[$j], $arr[$minPos]) = [$min, $arr[$j]];
}
}
/*
插入排序的工作原理是将数字插入到已排序列表的正确位置。
它从数组的第二项开始,并判断该项是否小于当前值。如果是这样,它将项目转移,并将较小的项目存储在其正确的位置。
然后,它移动到下一项,并且相同的原理继续下去,直到整个数组被排序。
*/
function insertionSort(array &$arr)
{
$len = count($arr);
for ($i = 1; $i < $len; $i++) {
$key = $arr[$i];
$j = $i - 1;
while ($j >= 0 && $arr[$j] > $key) {
$arr[$j + 1] = $arr[$j];
$j--;
}
$arr[$j + 1] = $key;
}
}
/**
* 归并排序
* 核心:两个有序子序列的归并(function merge)
* 时间复杂度任何情况下都是 O(nlogn)
* 空间复杂度 O(n)
* 发明人: 约翰·冯·诺伊曼
* 速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列
* 一般不用于内(内存)排序,一般用于外排序
*/
function mergeSort($arr)
{
$lenght = count($arr);
if ($lenght == 1) return $arr;
$mid = (int)($lenght / 2);
//把待排序数组分割成两半
$left = mergeSort(array_slice($arr, 0, $mid));
$right = mergeSort(array_slice($arr, $mid));
return merge($left, $right);
}
function merge(array $left, array $right)
{
//初始化两个指针
$leftIndex = $rightIndex = 0;
$leftLength = count($left);
$rightLength = count($right);
//临时空间
$combine = [];
//比较两个指针所在的元素
while ($leftIndex < $leftLength && $rightIndex < $rightLength) {
//如果左边的元素大于右边的元素,就将右边的元素放在单独的数组,并将右指针向后移动
if ($left[$leftIndex] > $right[$rightIndex]) {
$combine[] = $right[$rightIndex];
$rightIndex++;
} else {
//如果右边的元素大于左边的元素,就将左边的元素放在单独的数组,并将左指针向后移动
$combine[] = $left[$leftIndex];
$leftIndex++;
}
}
//右边的数组全部都放入到了返回的数组,然后把左边数组的值放入返回的数组
while ($leftIndex < $leftLength) {
$combine[] = $left[$leftIndex];
$leftIndex++;
}
//左边的数组全部都放入到了返回的数组,然后把右边数组的值放入返回的数组
while ($rightIndex < $rightLength) {
$combine[] = $right[$rightIndex];
$rightIndex++;
}
return $combine;
}
//快速排序
function qSort(array &$arr, int $p, int $r)
{
if ($p < $r) {
$q = partition($arr, $p, $r);
qSort($arr, $p, $q);
qSort($arr, $q + 1, $r);
}
}
function partition(array &$arr, int $p, int $r)
{
$pivot = $arr[$p];
$i = $p - 1;
$j = $r + 1;
while (true) {
do {
$i++;
} while ($arr[$i] < $pivot);
do {
$j--;
} while ($arr[$j] > $pivot);
if ($i < $j) {
list($arr[$i], $arr[$j]) = [$arr[$j], $arr[$i]];
} else {
return $j;
}
}
}
/**
* 桶排序
* 不是一种基于比较的排序
* T(N, M) = O(M + N) N是带排序的数据的个数,M是数据值的数量
* 当 M >> N 时,需要考虑使用基数排序
*/
function bucketSort(array &$data)
{
$bucketLen = max($data) - min($data) + 1;
$bucket = array_fill(0, $bucketLen, []);
for ($i = 0; $i < count($data); $i++) {
array_push($bucket[$data[$i] - min($data)], $data[$i]);
}
$k = 0;
for ($i = 0; $i < $bucketLen; $i++) {
$currentBucketLen = count($bucket[$i]);
for ($j = 0; $j < $currentBucketLen; $j++) {
$data[$k] = $bucket[$i][$j];
$k++;
}
}
}
PHP几个基本的排序算法
猜你喜欢
转载自blog.csdn.net/u013083541/article/details/82771945
今日推荐
周排行