zoukankan      html  css  js  c++  java
  • 冒泡排序(优化版)和快速排序

    冒泡排序原版

    分别使用usort和冒泡排序对数组按name的字符串长度排序

    $arr = array(
        array('id' => 0, 'name' => '123833'),
        array('id' => 0, 'name' => 'aaa'),
        array('id' => 0, 'name' => 'albabaababa'),
        array('id' => 0, 'name' => '12356'),
        array('id' => 0, 'name' => '123abc')
    );
    
    //自定义排序usort对数组排序
    function cmp($a,$b){     //$a,$b为数组的值两两进行比较
        $a = strlen($a['name']);
        $b = strlen($b['name']);
        if($a == $b) return 0;   
         return $a<$b ? -1 : 1;   //返回-1则交换顺序
    }
    usort($arr,"cmp");     //自定义排序,此处函数cmp需要加"",否则报错,不能写成cmp().
    
    //冒泡排序法
    for($i=0; $i<count($arr); $i++){
        for($j=0; $j<count($arr)-1; $j++){  //内层循环个数少一个
            if(strlen($arr[$j]) > strlen($arr[$j+1])){
                $tmp=$arr[$j];
                $arr[$j]=$arr[$j+1];
                $arr[$j+1]=$tmp;
            }
        }
    }
    
    echo "<pre>";
    print_r($arr);
    echo "</pre>";

     

    冒泡排序优化版

    原始的冒泡排序相对而言是非常耗时的,即使一个数组经过几轮交换已经变的有序了,例如[2,1,3,4,5,6,7]这个数组,经过第一轮,已经变成有序的了,但顽固的冒泡还是要继续进

    没有营养的两两比较,从而牺牲了时间。

    如果用一个flag来判断一下,当前数组是否已经有序,如果有序就退出循环,这样可以明显的提高冒泡排序的表现~

    由于冒泡排序的时间复杂度为O(n*n)所以当数据越多的时候,越慢,非常不适合大数据的排序。

    function bubbleSort($arr){
        $flag = true;
        $count = count($arr);
        for($i=0;$i<$count-1&&$flag;$i++){
            $flag = false;
            for($j=$count-1;$j>$i;$j--){ //和($j=0;$j<$count-$i-1;$j++)相同
                if($arr[$j] < $arr[$j-1]){
                    $flag = true;
                    $tmp = $arr[$j];
                    $arr[$j] = $arr[$j-1];
                    $arr[$j-1] = $tmp;
                }
            }
        }
    
        return $arr;
    }

    快速排序

    取第一个值与其他值进行比较,小的放在这个值的左边,大的放在这个值的右边,然后按照这个方式递归,退出递归的条件是数组的个数<=1。

    function quicksort($arr)
    {
        //如果个数不大于一,直接返回,退出循环的条件
        if (count($arr)<=1) {
            return $arr;
        }
    
        $val = $arr[0]; //取一个值,稍后用来比较
    
        $left = $right = [];
    
        //比$key大的放在右边,小的放在左边,注意循环从1开始,从0开始的话会一直循环,造成Segmentation fault
        for($i=1;$i<count($arr);$i++){
            if ($arr[$i] <= $val) {
                $left[] = $arr[$i];
            }else{
                $right[] = $arr[$i];
            }
        }
    
        $left = quicksort($left); //进行递归
        $right = quicksort($right);
    
        return array_merge($left, [$val], $right); //将左中右的值合并成一个数组
    }
  • 相关阅读:
    树状数组
    #135. 二维树状数组 3:区间修改,区间查询
    poj 2155 (二维树状数组 区间修改 求某点值)
    #133. 二维树状数组 1:单点修改,区间查询
    poj 3468 (区间修改 区间查询)
    树状数组 模板
    1535:【例 1】数列操作
    最通俗全面理解application context中的context是什么意思
    牛客哈理工小乐乐下象棋(深度理解bfs好题)
    牛客哈理工小乐乐打游戏(bfs深度理解好题)
  • 原文地址:https://www.cnblogs.com/leezhxing/p/3416262.html
Copyright © 2011-2022 走看看