排序算法总结

排序算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序O(n^2)O(n)O(n^2)O(1)稳定
选择排序O(n^2)O(n^2)O(n^2)O(1)不稳定
插入排序O(n^2)O(n)O(n^2)O(1)稳定
快速排序O(nlogn)O(nlogn)O(n^2) 逆序,有序都会最差平均O(logn) 最差O(n) 即栈的深度不稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定
希尔排序O(n^1.3)-O(n^2)O(1)不稳定
基数排序O(d*(n+r))O(d*(n+r))O(d*(n+r))O(r)稳定
计数排序O(n + k)O(n + k)O(n + k)O(n + k)稳定

冒泡排序

public function bubbleSort($nums){
    $len = count($nums);
    $turn = 0;
    $flag = false;
    for($i = 0; !$flag && $i < $len; $i-){
        $flag = true;
        for($j = $len - 1; $j > $i; $j--){
            if($nums[$j] < $nums[$j - 1]){
                $temp = $nums[$j];
                $nums[$j] = $nums[$j - 1];
                $nums[$j - 1] = $temp;
                $flag = true;
            }
        }
    }
}   

选择排序

2,2,1 => 1,2,2 不稳定

public function selectPop($nums){
    $len = count($nums);
    for($i = 1; $i < $len; $i++){
        $min = $i;
        for($j = $i; $j < $len; $j++){
            if($nums[j] < $nums[min])
                $min = $j;
        }
        $temp = $nums[$i];
        $nums[$i] = $nums[$min];
        $nums[$min] = $temp;
    }
}

插入排序

public function insertSort($nums){
    $len = count($nums);
    for($i = 1; $i < $len; $i++){
        if($nums[$i] < $nums[$i - 1]){
            $temp = $nums[$i];
            $j = $i - 1;
            for(; $temp < $nums[$j] && $j >= 0; $j--)
                $nums[$j + 1] = $nums[$j];
            $nums[$j + 1] = $temp;
        }
    }
}

快速排序

public function quickSort($nums, $start, $end){
    if($start < $end){
        $pivotPos = partition($nums, $start, $end);
        quickSort($nums, $start, $pivotPos - 1);
        quickSort($nums, $pivotPos + 1, $high)
    }
}

public function partition($nums, $start, $end){
    $temp = $nums[$start];
    while($start < $end){
        while($start < $end && $nums[$end] >= $temp) $end--;
        $nums[$start] = $nums[$end];
        while($start < $end && $nums[$start] <= $temp) $start++;
        $nums[$end] = $num[$start];
    }
    $nums[$start] = $temp;
    return $start;
}

归并排序

public function mergeSort($nums, $start, $end){
    if($start < $end){
        $mid = ($start + $end) / 2;
        mergeSort($nums, $start, $mid);
        mergeSort($nums, $mid + 1, $end);
        merge($nums, $start, $mid, $end);
    }
}

public function merge($nums, $start, $mid, $end){
    $temp = [];
    for($i = $start; $i < $end; $i++)
        $temp[] = $nums[$i];
    $i = 0;
    $j = $mid - $start;
    for($k = $start; $i <= $mid - $start && $j < count($temp); $k++)
        $nums[$k] = $temp[$i] > $temp[$j] ? $temp[$i++] : $temp[$j++];
    while($i <= $mid - $start) $nums[$k++] = $temp[$i++];
    while($j < count($temp))  $nums[$k++] = $temp[$j++];
}

堆排序

nums[0]处不存储数据,当作哨兵位,用来存储中间值。还有个好处是可以让数据从1开始算起,这样算左右节点的时候比较方便

public function heapSort($nums, $len){
    buildMaxHeap($nums, $len);
    for($i = $len, $i > 1; $i--){
        $temp = $nums[1];//堆顶下标为1
        $nums[1] = $nums[$i];
        $nums[$i] = $temp;//将最大元素放到最后,整理前面i - 1个元素,使之形成新的堆
        adjustDown($nums, 1, $i - 1);
    }
}

public function buildMaxHeap($nums, $len){
    for($i = $len / 2; $i > 0; $i--)
        adjustDown($nums, $i, $len);
}

public function adjustDown($nums, $k, $len){
    $nums[0] = $nums[$k];
    for($i = 2 * $k; $i < $len; $i *= 2){//$i * 2向下调整
        if($i < $len && $nums[$i] < $nums[$i + 1])//因为从1开始算数据,所以下标为2的一定为左节点
            $i++;
        if($nums[0] >= $nums[i]) break;
        else{
            $nums[$k] = $nums[$i];
            $k = $i;
        }
    }
    $nums[$k] = $nums[0];
}

//插入新元素的时候,将新元素放在堆底,然后向上调整
public function adjustUp($nums, $k){
    $nums[0] = $nums[$k];
    $i = $k / 2;
    while($i > 0 && $nums[i] < $nums[0]){
        $nums[$k] = $nums[i];
        $k = $i;
        $i = $k / 2;
    }
    $nums[$k] = $nums[0];
}

希尔排序

3,2,2 => 2,2,3 不稳定

public function shellSort($nums, $len, $n){
    for($dk = $len / 2; $dk >= 1; $dk /= 2)
        for($i = $dk + 1; $i <= 2*$dk; $i++)
            if($nums[$i] < $nums[$i - $dk]){
                $nums[0] = $nums[$i];
                $j = $i - $dk;
                for(; $j > 0 && $nums[0] < $nums[$j]; $j -= $dk)
                    $nums[$j + $dk] = $nums[$j];
                $nums[$j + $dk] = $nums[0];
            }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值