• 冒泡排序


    分析与解答:

    冒泡排序,顾名思义就是整个过程就像气泡一样往上升,单向冒泡排序的基本思想是(假设由小到大排序):对于给定的 n 个记录,从第一个记录开始依次对相邻的两个记录进行比较,当前面的记录大于后面的记录时,交换其位置,进行一轮比较和换位后,n 个记录中的最大记录将位于第 n 位;然后对前(n-1)个记录进行第二轮比较;重复该过程直到进行比较的记录只剩下一个时为止。算法原理如下:
    1)比较相邻的元素,如果第一个比第二个大,那么就交换这两个元素。
    2)对每一对相邻元素做同样的工作,从第一对开始到最后一对结束,最后的元素应该会是最大的数。
    3)除了最后一个元素外,针对其他的元素重复以上的步骤。
    4)对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较为止。
    以数组 array(36, 25, 48, 12, 25, 65, 43, 57)为例,具体排序过程如下:
    初始状态:[36 25 48 12 25 65 43 57]
    1 趟排序:[25 36 12 25 48 43 57] 65]
    2 趟排序:[25 12 25 36 43 48] 57 65]
    3 趟排序:[12 25 25 36 43] 48 57 65]
    4 趟排序:[12 25 25 36] 43 48 57 65]
    5 趟排序:[12 25 25] 36 43 48 57 65]
    6 趟排序:[12 25] 25 36 43 48 57 65]
    7 趟排序:[12] 25 25 36 43 48 57 65]
    根据以上的实现原理,实现代码如下:

    <?php
    function maopao($arr){
        $len = count($arr);
    
        for($i = 1; $i < $len;$i++){
            for($k = 0; $k < $len; $k++){
                if($arr[$k] > $arr[$k+1]){
                    $tmp = $arr[$k+1];
                    $arr[$k+1] = $arr[$k];
                    $arr[$k] = $tmp;
                }
            }
        }
    
        return $arr;
    }
    
    $arr = [36,25,48,12,25,65,43,57];
    echo "排序前";
    foreach ($arr as $k => $val){
        echo $val.' ';
    }
    echo "
    排序后";
    $arr = maopao($arr);
    foreach ($arr as $k => $val){
        echo $val.' ';
    }
    

    程序的运行结果为

    排序前36 25 48 12 25 65 43 57
    排序后12 25 25 36 43 48 57 65
    

    在传统的冒泡排序基础上,可以进一步改进冒泡排序算法,通过设置一个标志 bool,用于记录每趟排序中最后一次交换的位置。由于 bool 标志之后的记录均已交换到位,因此下一趟排序时只要扫描到 bool 位置即可,不需要再对 bool 后的循环排序。改进后的冒泡排序算法 2 如下:

    <?php
    function maopao($arr){
        $i = count($arr) - 1; //初始时,最后位置保持不变
    
        while ($i > 0){
            $bool = 0;
            for($j = 0; $j < $i; $j++){
                if($arr[$j] > $arr[$j+1]){
                    $bool = $j;  //记录交换的位置
                    $tmp = $arr[$j];
                    $arr[$j] = $arr[$j+1];
                    $arr[$j+1] = $tmp;
                }
    
            }
            $i = $bool; //为下一趟排序做准备
        }
    
        return $arr;
    }
    
    $arr = [36,25,48,12,25,65,43,57];
    echo "排序前";
    foreach ($arr as $k => $val){
        echo $val.' ';
    }
    echo "
    排序后";
    $arr = maopao($arr);
    
    foreach ($arr as $k => $val){
        echo $val.' ';
    }
    

    程序的运行结果为

    排序前36 25 48 12 25 65 43 57
    排序后12 25 25 36 43 48 57 65
    

    因为传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,所以可以考虑在每趟排序中进行正向和反向两遍冒泡的方法,一次得到最大者和最小者,从而可使排序趟数将近减少一半。再次改进后的冒泡排序法 3 如下:

    <?php
    function maopao($arr){
        $low = 0;
        $high = count($arr) - 1;
        while($low < $high){
            for($j = $low; $j<$high;++$j){
                if($arr[$j] > $arr[$j+1]){
                    $tmp = $arr[$j];
                    $arr[$j] = $arr[$j+1];
                    $arr[$j+1] = $tmp;
                }
            }
            --$high;
            for($j = $high; $j < $low; --$j){
                if($arr[$j]< $arr[$j-1]){
                    $tmp = $arr[$j];
                    $arr[$j] = $arr[$j-1];
                    $arr[$j-1] = $tmp;
                }
            }
            ++$low;
        }
    
    
        return $arr;
    }
    
    $arr = [36,25,48,12,25,65,43,57];
    echo "排序前";
    foreach ($arr as $k => $val){
        echo $val.' ';
    }
    echo "
    排序后";
    $arr = maopao($arr);
    
    foreach ($arr as $k => $val){
        echo $val.' ';
    }
    

    程序的运行结果为

    ```shell
    排序前36 25 48 12 25 65 43 57
    排序后12 25 25 36 43 48 57 65
    
    
    以上介绍的冒泡排序法中,它们执行的效率:
    传统冒泡排序法 < 改进后冒泡排序法 2< 改进后冒泡排序法 3。
    算法性能分析:
    最佳情况:T(n)=O(n),当输入的数据为正序时,则是最佳情况。
    最差情况:T(n)=O(n2),当输入的数据是反序时,则是最差情况,需依次从头到尾重新排序。
    平均情况:T(n)=O(n2)。
  • 相关阅读:
    ubuntu重复登录问题
    CUDA相关问题
    pytorch安装(使用pip3装到conda环境下)
    ubuntu16.04 anaconda的安装和卸载
    vscode插件安装失败的解决方案
    使用ffmpeg进行视频截图
    Spring加载早期获取BasePackage
    chrome最耐看的主题
    针对MySQL的MVCC多版本并发控制的一些总结
    docker创建mysql容器,并挂载数据+配置
  • 原文地址:https://www.cnblogs.com/hardy-wang/p/13121795.html
Copyright © 2020-2023  润新知