php-冒泡排序、插入排序、选择排序、希尔排序

2020-09-15  本文已影响0人  淡淡de盐

冒泡排序、插入排序、选择排序、希尔排序 时间复杂度 O(N²)

image.png

稳定性: 这个概念是说,如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。
原地排序算法:特指空间复杂度是O(1)的排序算法。

开始前一句话总结

冒泡排序

function bubbleSort($arr)
{
    $len = count($arr);
    for ($i = 1; $i < $len; $i++) {
        for ($k = 0; $k < $len - $i; $k++) {
            if ($arr[$k] > $arr[$k + 1]) {
                $tmp         = $arr[$k + 1];
                $arr[$k + 1] = $arr[$k];
                $arr[$k]     = $tmp;
            }
        }
    }

    return $arr;
}

时间复杂度: O(N²)
空间复杂度: O(1)
稳定、原地排序算法

冒泡比较简单,从左到右,相邻比较。

冒泡

插入排序

function insertSort($arr)
{
    $len = count($arr);
    for ($i = 1; $i < $len; $i++) {
        $val = $arr[$i];
        for ($j = $i - 1; $j >= 0; $j--) {
            if ($arr[$j] > $val) {
                $arr[$j + 1] = $arr[$j];
            } else {
                break;
            }
        }
        $arr[$j + 1] = $val;
    }

    return $arr;
}

时间复杂度: O(N²)
空间复杂度: O(1)
稳定、原地排序算法

排序描述

为什么叫插入排序,很容易就联想到一个有序的数组,我们往里面添加一个新的数据后,如何继续保持数据有序呢?很简单,我们只要遍历数组,找到数据应该插入的位置将其插入即可。如下图已有一个数组:

插入排序
首先我们将数组中的数据分为两个区间,已排序区间未排序区间

选择排序

function selectSort($arr)
{
    $len = count($arr);
    for ($i = 0; $i < $len-1; $i++) {
        $min_index = $i;
        for ($j = $i + 1; $j < $len; $j++) {
            if ($arr[$j] < $arr[$min_index]) {
                $min_index = $j;
            }
        }
        if ($i != $min_index) {
            $tmp             = $arr[$i];
            $arr[$i]         = $arr[$min_index];
            $arr[$min_index] = $tmp;
        }
    }

    return $arr;
}

时间复杂度: O(N²)
空间复杂度: O(1)
不稳定、原地排序算法

排序描述

选择排序算法的实现思路有点类似插入排序,也分已排序区间未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。

选择排序

为什么是不稳定的排序算法

比如 5,8,5,2,9 这样一组数据,使用选择排序算法来排序的话,第一次找到最小元素 2,与第一个 5 交换位置,那第一个 5 和中间的 5 顺序就变了,所以就不稳定了。正是因此,相对于冒泡排序和插入排序,选择排序就稍微逊色了。

希尔排序

    function shellSort(&$arr)
    {
        $count = count($arr);
        $inc   = $count;

        do {
            $inc = ceil($inc / 2);
            for ($i = $inc; $i < $count; $i++) {
                $tmp = $arr[$i];
                for ($j = $i - $inc; $j >= 0 && $arr[$j + $inc] < $arr[$j]; $j -= $inc) {
                    $arr[$j + $inc] = $arr[$j];
                }
                $arr[$j + $inc] = $tmp;
            }
        } while ($inc > 1);
    }

排序描述

希尔排序就是插入排序的一种改进,插入排序在基本有序或记录数比较少时效率会高。
希尔就是利用分组和基本有序来提升效率。
一个数组$arr = [9, 1, 5, 8, 3, 7, 4, 6, 2];
最关键就是怎么把它变成一个基本有序,什么是基本有序呢,就是基本小数在左,不大不小在中间,大数在右
比如像 [2, 1, 3, 6, 4, 7, 5, 8, 9] 这样可以称为基本有序,怎么实现的呢,下面简单描述下过程,然后看代码去领悟其中含义。

\color{red}{其实含义很简单,就是从插入排序一位一位的判断插入,变成了跳跃式插入。}

第一轮 $inc=5 时,i 从 5 循环到 8,j = i - inc$inc = ceil($inc / 2); = 9/2 =5`

第二轮 $inc=3 时,i 从 3 循环到 8 ,j = i - inc$inc = ceil($inc / 2); = 5/2 =3`

第三轮 $inc = 2 时,i 从 2 循环到 8 ,j = i - inc$inc = intval(3 / 2); = 3/2 = 2

第四轮 $inc = 1 时,i 从 1 循环到 8 ,j = i - inc$inc = intval($inc / 3) + 1; = 2/3+1 = 1

[1, 2, 3, 4, 6, 5, 7, 8, 9]

上一篇 下一篇

猜你喜欢

热点阅读