zoukankan      html  css  js  c++  java
  • 徒手优化冒泡排序

    冒泡排序是一种比较粗暴的基本排序,也是算法里面很常规的。今天我用php和js作为实现语言,一步一步去优化这个算法。常规的写法如下:

    php部分:

     1 <?php
     2 /**
     3  * 冒泡排序
     4  * User:freephp
     5  * Date: 2015/10/9
     6  * Time: 14:09
     7  */
     8 
     9 function bubbleSort($arr) {
    10     if (empty($arr)) return false;
    11     $len = count($arr);
    12 
    13     for($i=0;$i<$len-1;$i++){
    14         for ($j=0; $j < $len-i-1; $j++) {
    15             if($arr[$j+1] < $arr[$j]){ // 从小到大排序
    16                 $tmp=$arr[$j];
    17                 $arr[$j]=$arr[$j+1];
    18                 $arr[$j+1]=$tmp;
    19             }
    20         }
    21     }
    22     return $arr;
    23 }
    24 
    25 $arr1 = [33,23,54,1,4,7]; // php5的新写法
    26 $newArr = bubbleSort($arr1);
    27 print_r($newArr);

    打印出来结果为:

    Array
    (
    [0] => 1
    [1] => 4
    [2] => 23
    [3] => 33
    [4] => 54
    )

    js实现:

    <script type="application/javascript">
        function bubbleSort(arr) {
            var len = arr.length;
            if (len == 0 ) {console.log('不能为空数组!'); return false;}
            for (var i=0;i<len-1;i++) {
                for (var j=0;i<len-1-i;j++) {
                    if (arr[j] > arr[j+1]) {
                        var temp = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = temp;
                    }
                }
            }
            return arr;
        }
    
        var arr=[32,55,78,43,78,10,45,20,9,89];
        bubbleSort(arr);
    
        
        for(var i=0;i<arr.length;i++){
            document.write(arr[i]+",");
        }
    
    </script>

    都是最原始的实现方式,双层循环一遍一遍去两两比较。时间复杂度为O(n*n).

    做一下思考,如果在一趟排序中没有数据发生交换,那么就已经排好序了。我们只需要加个flag来做标识。

    function bubbleSort2($arr) {
        if (empty($arr)) return false;
        $len = count($arr);
    
    
        for($i=0;$i<$len-1;$i++){
            // 是否发生交换
            $flag = false;
            for ($j=0; $j < $len-i-1; $j++) {
                if($arr[$j+1] < $arr[$j]){ // 从小到大排序
                    $tmp=$arr[$j];
                    $arr[$j]=$arr[$j+1];
                    $arr[$j+1]=$tmp;
                    $flag = true;
                }
    
            }
            if (!$flag) return $arr;
        }
        return $arr;
    }
    
    $arr1 = [33,23,54,1,4,7,6]; // php5的新写法
    $startTime = microtime(true);
    $newArr = bubbleSort($arr1);
    $endTime =microtime(true);
    $cost = $endTime - $startTime;
    print_r($newArr);
    echo "bubbleSort func cost time is:{$cost}
    ";
    $startTime = microtime(true);
    $newArr = bubbleSort2($arr1);
    $endTime =microtime(true);
    $cost = $endTime - $startTime;
    echo "bubbleSort2 func cost time is:{$cost}
    ";
    print_r($newArr);

    打印出来如下结果:

    Array
    (
    [0] => 1
    [1] => 4
    [2] => 6
    [3] => 7
    [4] => 23
    [5] => 33
    [6] => 54
    )
    bubbleSort func cost time is:0.000133037567139
    bubbleSort2 func cost time is:0.000128984451294
    Array
    (
    [0] => 1
    [1] => 4
    [2] => 6
    [3] => 7
    [4] => 23
    [5] => 33
    [6] => 54
    )

    可见改良后的bubbleSort2效率高得明显。同样js实现如下:

    function bubbleSort2(arr) {
            var len = arr.length;
            if (len == 0 ) {console.log('不能为空数组!'); return false;}
    
            for (var i=0;i<len-1;i++) {
                var flag = false; // 每一趟外层比较的交换标记,默认是false
                for (var j=0;i<len-1-i;j++) {
                    if (arr[j] > arr[j+1]) {
                        var temp = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = temp;
                        flag = true; // 发生交换
                    }
                }
                if (!flag) return arr;
            }
            return arr;
        }

    然而,我们既然都用了标识,那么更进一步在每次内循环比较的时候记录脚标,可以更加缩小比较范围。

    顺便利用list函数巧妙交换数组,php实现如下:

    
    
    function bubbleSortPro($arr) {
    if (empty($arr)) return false;
    $last = count($arr) - 1;
    $num = $last + 1;
    $lastCursor = 0;
    for($i=0;$i < $last;$i++){
    for ($j=0; $j < $last-$i; $j++) {
    if($arr[$j+1] < $arr[$j]){ // 从小到大排序
    list($arr[$j+1], $arr[$j]) = array($arr[$j], $arr[$j+1]);
    $lastCursor = $j+1;
    }

    }
    if ($lastCursor == $num) return $arr;
    }
    return $arr;
    }



    调用之后的结果为:

    bubbleSortPro func cost time is:6.60419464111E-5
    Array
    (
    [0] => 1
    [1] => 4
    [2] => 6
    [3] => 7
    [4] => 23
    [5] => 33
    [6] => 54
    )

    js原理一样,如下所示:

     function bubbleSortPro(arr) {
            var len = arr.length;
            if (len == 0 ) {console.log('不能为空数组!'); return false;}
            var last = len -1;
            var lastCusor = 0;
            for (var i=0;i<last;i++) {
    
                for (var j=0;i<last-i;j++) {
                    if (arr[j] > arr[j+1]) {
                        var temp = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = temp;
                        lastCusor = j+1;
                    }
                }
                if (lastCusor == len) return arr;
            }
            return arr;
        }

    总结:缩小循环和判断游标范围,人为优化算法是关键。

  • 相关阅读:
    [NPM] Avoid Duplicate Commands by Calling one NPM Script from Another
    [Algorithm] Dynamic programming: Find Sets Of Numbers That Add Up To 16
    [React] Refactor a Class Component with React hooks to a Function
    [Algorithm] Construct a Binary Tree and Binary Search
    设计模式(装饰者模式)
    IOS设计模式之二(门面模式,装饰器模式)
    IOS设计模式之三(适配器模式,观察者模式)
    linux内核源码阅读之facebook硬盘加速flashcache之五
    IOS设计模式之四(备忘录模式,命令模式)
    DRP总结
  • 原文地址:https://www.cnblogs.com/freephp/p/4863993.html
Copyright © 2011-2022 走看看