/***
* @param $arr
* @return mixed
* 冒泡排序【重复比较两个相邻的元素,如果位置错误则对调位置,直至没有元素需要对换】
* 分类 -------------- 内部比较排序
* 数据结构 ---------- 数组
* 最差时间复杂度 ---- O(n^2)
* 最优时间复杂度 ---- 如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,可以把最优时间复杂度降低到O(n)
* 平均时间复杂度 ---- O(n^2)
* 所需辅助空间 ------ O(1)
* 稳定性 ------------ 稳定
*/
private function bubbleSort($arr){
for ($i=0;$i<count($arr);$i++){
for ($j=0;$j<count($arr)-1;$j++){
if($arr[$j] > $arr[$j+1]){
$tmp = $arr[$j];
$arr[$j]=$arr[$j+1];
$arr[$j+1] = $tmp;
}
}
}
return $arr;
}
/**
* @param $arr
* @return mixed
* 鸡尾酒排序【又叫定向冒泡排序,冒泡排序的一种改进,先向右排序出最大的那个,然后向左排序出最小的,周而复此】
* 分类 -------------- 内部比较排序
* 数据结构 ---------- 数组
* 最差时间复杂度 ---- O(n^2)
* 最优时间复杂度 ---- 如果序列在一开始已经大部分排序过的话,会接近O(n)
* 平均时间复杂度 ---- O(n^2)
* 所需辅助空间 ------ O(1)
* 稳定性 ------------ 稳定
*/
private function cocktailSort($arr){
$left = 0;
$right = count($arr)-1;
while ($left < $right){
for ($i=$left;$i<$right;$i++){
if($arr[$i] > $arr[$i+1]){
$tmp = $arr[$i];
$arr[$i]=$arr[$i+1];
$arr[$i+1] = $tmp;
}
}
$left++;
for ($i=$right;$i>$left;$i--){
if($arr[$i-1] > $arr[$i]){
$tmp = $arr[$i-1];
$arr[$i-1]=$arr[$i];
$arr[$i] = $tmp;
}
}
$right--;
}
return $arr;
}
/**
* @param $arr
* @return mixed
* 选择排序【找出第1/2/3/4/../n个最小(大)的值放到相应的位置,然后继续找出下一个未排序的最小(大)值】
* 分类 -------------- 内部比较排序
* 数据结构 ---------- 数组
* 最差时间复杂度 ---- O(n^2)
* 最优时间复杂度 ---- O(n^2)
* 平均时间复杂度 ---- O(n^2)
* 所需辅助空间 ------ O(1)
* 稳定性 ------------ 不稳定
*/
private function chooseSort($arr){
for ($i=0;$i<count($arr);$i++){
$min = $i;
//因为是从i开始比较,所以i+1
for ($j=$i+1;$j<count($arr);$j++){
if($arr[$min]>$arr[$j]){
$min = $j;
}
}
if($min != $i){
$tmp = $arr[$i];
$arr[$i] = $arr[$min];
$arr[$min] = $tmp;
}
}
return $arr;
}
/**
* @param $arr
* @return mixed
* 插入排序【往左一个个比较】
* 分类 ------------- 内部比较排序
* 数据结构 ---------- 数组
* 最差时间复杂度 ---- 最坏情况为输入序列是降序排列的,此时时间复杂度O(n^2)
* 最优时间复杂度 ---- 最好情况为输入序列是升序排列的,此时时间复杂度O(n)
* 平均时间复杂度 ---- O(n^2)
* 所需辅助空间 ------ O(1)
* 稳定性 ------------ 稳定
*/
private function insertSort($arr){
for ($i=1;$i<count($arr);$i++){
$get = $arr[$i];
$j = $i-1;
while($j>=0 && $arr[$j]>$get){
$arr[$j+1] = $arr[$j];
$j--;
}
$arr[$j+1] = $get;
}
return $arr;
}
/**
* 希尔排序(递减增量排序,插入排序的一种更搞笑改进版本)
* 分类 -------------- 内部比较排序
* 数据结构 ---------- 数组
* 最差时间复杂度 ---- 根据步长序列的不同而不同。已知最好的为O(n(logn)^2)
* 最优时间复杂度 ---- O(n)
* 平均时间复杂度 ---- 根据步长序列的不同而不同。
* 所需辅助空间 ------ O(1)
* 稳定性 ------------ 不稳定
*/
private function shellSort($arr){
$h = 0;
$count = count($arr);
while($h<$count){
$h=3*$h+1;
}
while ($h>=1){
for ($i=$h;$i<$count;$i++){
$j=$i-$h;
$get = $arr[$i];
while ($j>=0 && $arr[$j] > $get){
$arr[$j+$h] = $arr[$j];
$j = $j-$h;
}
$arr[$j+$h] = $get;
}
$h = ($h-1)/3;
}
return $arr;
}
/**
* 归并排序
* 分开 -------------- 内部比较排序
* 数据结构 ----------- 数组
* 最差时间复杂度 ------ O
* 最有时间复杂度 ------ O
* 平均时间复杂度 ------ O
* 所需辅助空间 -------- O(n)
* 稳定性 ------------- 稳定
*/
private function mergeSort($arr){
$len = count($arr);
if($len <= 1) return $arr;
$mid = intval($len/2);
$leftArr = array_slice($arr,0,$mid);
$rightArr = array_slice($arr,$mid);
$leftArr = $this->mergeSort($leftArr);
$rightArr = $this->mergeSort($rightArr);
$arr = $this->mergeArr($leftArr,$rightArr);
return $arr;
}
private function mergeArr($arr1,$arr2){
$arr3 = array();
while (count($arr1) && count($arr2)){
$arr3[] = $arr1['0']<$arr2['0']?array_shift($arr1):array_shift($arr2);
}
return array_merge($arr3,$arr1,$arr2);
}