//实例 [5,2,3,1,23413,333,2323,123412341,12323]
class Solution {
/**
* @param Integer[] $nums
* @return Integer[]
*/
//1. 冒泡
function sortArray1($nums) {
$len = count($nums);
for($i = 1; $i < $len; $i++){
for($j = 0; $j < $len - $i; $j++){
if($nums[$j] > $nums[$j+1]){
$tmp = $nums[$j+1];
$nums[$j+1] = $nums[$j];
$nums[$j] = $tmp;
}
}
}
return $nums;
}
//2. 插入排序
function sortArray2($nums)
{
$len = count($nums);
for($i = 1; $i < $len; $i++){
$tmp = $nums[$i];
for($j = $i-1; $j >= 0; $j--){
if($tmp < $nums[$j]){
$nums[$j+1] = $nums[$j];
$nums[$j] = $tmp;
}else{
break;
}
}
}
return $nums;
}
//3. 选择排序
function sortArray3($nums){
$len = count($nums);
for($i = 0; $i < $len; $i++){
$p = $i;
for($j = $i+1; $j < $len; $j++){
if($nums[$p] > $nums[$j]){
$p = $j;
}
}
if($i != $p){
$tmp = $nums[$p];
$nums[$p] = $nums[$i];
$nums[$i] = $tmp;
}
}
return $nums;
}
//4. 快速排序,用第一个数 与 其之后的数比较
function sortArray4($nums){
$len = count($nums);
if($len <= 1){
return $nums;
}
$baseNum = $nums[0];
$leftArr = $rightArr = [];
for($i = 1; $i < $len; $i++){
if($baseNum > $nums[$i]){
$leftArr[] = $nums[$i];
}else{
$rightArr[] = $nums[$i];
}
}
$leftArr = $this->sortArray($leftArr);
$rightArr = $this->sortArray($rightArr);
return array_merge($leftArr, [$baseNum], $rightArr);
}
//5. 归并排序
function sortArray5($nums) {
$len = count($nums);
if($len <= 1){
return $nums;
}
return $this->mergeR($nums, 0, $len-1);
}
function mergeR($nums, $start, $end){
if($start >= $end){
return [$nums[$start]];
}
$mid = (int)(($start + $end) / 2);
$leftArr = $this->mergeR($nums, $start, $mid);
$rightArr = $this->mergeR($nums, $mid+1, $end);
return $this->merge($leftArr, $rightArr);
}
function merge($leftArr, $rightArr){
$leftLen = count($leftArr);
$rightLen = count($rightArr);
$i = $j = 0;
$tmp = [];
while($i < $leftLen && $j < $rightLen){
if($leftArr[$i] < $rightArr[$j]){
$tmp[] = $leftArr[$i++];
}else{
$tmp[] = $rightArr[$j++];
}
}
while($i < $leftLen){
$tmp[] = $leftArr[$i++];
}
while($j < $rightLen){
$tmp[] = $rightArr[$j++];
}
return $tmp;
}
//6.堆排序
function sortArray($arr){
$count = count($arr);
// 建堆 (下标小于或等于floor($count/2)-1的节点都是要调整的节点)
for($i = floor($count / 2) - 1; $i >= 0; $i --){
$this->heapAdjust($arr, $i, $count);
}
// 调整堆
for($i = $count - 1; $i >= 0; $i--){
//将堆顶元素与最后一个元素交换
$this->swap($arr,0,$i);
$this->heapAdjust($arr,0,$i - 1);
}
return $arr;
}
//调整 $arr[$start]的关键字,使$arr[$start]、$arr[$start+1]、、、$arr[$end]成为一个大根堆(根节点最大的完全二叉树)
//注意这里节点 s 的左右孩子是 2*s + 1 和 2*s+2 (数组开始下标为 0 时)
function heapAdjust(array &$arr,$start,$end){
$temp = $arr[$start];
//沿关键字较大的孩子节点向下筛选
//左右孩子计算(我这里数组开始下标识 0)
//左孩子2 * $start + 1,右孩子2 * $start + 2
for($j = 2 * $start + 1;$j <= $end;$j = 2 * $j + 1){
if( $j < $end && isset($arr[$j + 1]) && $arr[$j] < $arr[$j + 1]){
$j ++; //转化为右孩子
}
if($temp < $arr[$j]){
//将根节点设置为子节点的较大值
$arr[$start] = $arr[$j];
$start = $j;
}
}
$arr[$start] = $temp;
}
//交换2个值
function swap(&$arr, $a, $b){
$temp = $arr[$a];
$arr[$a] = $arr[$b];
$arr[$b] = $temp;
}
}