tips: php基础算法 鸡尾酒来源于网络
<?php
// 一个数组
$arr = [3,7,4,8,0,34,67,3,38,54,76,9,25,74,44];
// 冒泡排序 O(N^2) 可进行边界值优化 减少比较排序次数,鸡尾酒同
function MaoPao($arr) {
$count = count($arr);
for ($i = 0; $i < $count; $i++) {
for ($j = $count - 1; $j > $i ; $j--) {
if ($arr[$j] < $arr[$j - 1]) {
$_tmp = $arr[$j];
$arr[$j] = $arr[$j - 1];
$arr[$j - 1] = $_tmp;
}
}
}
return $arr;
}
// $arr_maopao = MaoPao($arr);
// echo "冒泡排序:";
// print_r($arr_maopao);
// echo "\r\n";
# 鸡尾酒排序
# 思路:基于冒泡 ,但是先正序排,然后倒序排(并加以冒泡的改进算法)
function cocktailSort($arr,$sort='asc'){
$sorted = false;
$bottom = 0;
$top = count($arr)-1;
while(!$sorted){
$sorted = true;
for ($i = $bottom; $i < $top; $i++) {
if(($arr[$i]>$arr[$i+1]&&$sort=='asc')||($arr[$i]<$arr[$i+1]&&$sort=='desc')){
$temp = $arr[$i+1];
$arr[$i+1] = $arr[$i];
$arr[$i] = $temp;
$sorted = false;//需要交换元素说明数组还没有被排序好
}
}
//然后再反向走一趟
//$top-1是因为拥有最大(小)值的元素已经在数组的顶端位置了
$top--;
for ($i = $top; $i > $bottom; $i--) {
if(($arr[$i]<$arr[$i-1]&&$sort=='asc')||($arr[$i]>$arr[$i-1]&&$sort=='desc')){
$temp = $arr[$i-1];
$arr[$i-1] = $arr[$i];
$arr[$i] = $temp;
$sorted = false;
}
}
//$bottom+1是因为是拥有最小(大)值得元素已经在数组的底部
$bottom++;
}
return $arr;
}
// $res = cocktailSort($arr);
// var_dump($res);
# 快速排序
# 思路:存在多个无序,则以基准数拆分数列 最终结果类似为中序遍历二叉树
function KuaiPai ($arr) {
$count = count($arr);
// $key = $arr[0]; // 基准数
$left = $right = array(); // 定义新分区
$l_len = $r_len = 0; // 记录左右分区长度
for ($i = 1; $i < $count; $i++) {
if ($arr[$i] < $arr[0]) {
$left[] = $arr[$i];
$l_len++;
} else {
$right[] = $arr[$i];
$r_len++;
}
}
if ($l_len > 1) {
$left = KuaiPai($left);
}
if ($r_len > 1) {
$right = KuaiPai($right);
}
// $new_arr = $left;
$new_arr = [];
$new_arr = $left;
$new_arr[] = $arr[0];
// array_merge($new_arr,$right);
for($i = 0; $i < $r_len; $i++) {
$new_arr[] = $right[$i];
}
return $new_arr;
}
// $arr_kp = KuaiPai($arr);
// echo "快速排序:";
// print_r($arr_kp);
// echo "\r\n";
// 选择排序 n^2 / 2 选出最小值
function XuanZe ($arr) {
$count = count($arr);//获取数组长度
for ($i = 0; $i < $count - 1; $i++) {
$_min = $arr[$i];
$_min_sub = $i; // 定位最小值下标进行交换
for ($j= $i + 1; $j < $count; $j++) {
if ($arr[$j] < $_min) {
$_min = $arr[$j];
$_min_sub = $j;
}
}
$arr[$_min_sub] = $arr[$i];
$arr[$i] = $_min;
}
return $arr;
}
// $arr_xz = XuanZe($arr);
// echo "选择排序:";
// print_r($arr_xz);
// echo "\r\n";
// 插入排序 n^2
// 每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
function ChaRu ($arr) {
$len=count($arr);
for($i=1; $i<$len; $i++) {
$tmp = $arr[$i];
//内层循环控制,比较并插入
for($j=$i-1;$j>=0;$j--) {
if($tmp < $arr[$j]) {
//发现插入的元素要小,交换位置,将后边的元素与前面的元素互换
$arr[$j+1] = $arr[$j];
$arr[$j] = $tmp;
} else {
//如果碰到不需要移动的元素,由于是已经排序好是数组,则前面的就不需要再次比较了。
break;
}
}
}
return $arr;
}
$arr_cr = ChaRu($arr);
echo "插入排序:";
print_r($arr_cr);
echo "\r\n";