zoukankan      html  css  js  c++  java
  • 快速排序

    <?php
    /*
        算法复杂度:(1)最好的情况和正常情况是:N*logN;
                  (2)最坏的情况是正着排好序的数组复杂度是:O(N^2);
        主要思想:
                    选取一个元素作为 pivot,随便取哪个位置的都行,一般取第一个;
                    将数值小于 pivot 的数字都放到 pivot 的左边,大于的放在右边;
                    那么,此时 pivot 这个数的位置就是排好序后的位置了。
                    再递归处理该 pivot 之前的数组,和之后的数组就行了。
                    -- 第二种方式貌似更好理解写。
    */
    function QuickSort( & $arr, $left, $right) {    // 使用数组引用
            /*
                递归的结束条件。同时也是该函数执行的前提。————数组元素个数小于1则推出。
                两个元素:$left = 0; $right = 1. 即:0 ~ 1
            */
            if($right - $left <= 0) {
                return 0;
            }
        /*
            采用“挖坑填数”的方式来对一个数组的内容进行一次调整:
            1、$i = $Left; $j = $Right; 将基准数挖出(存放到$pivot),形成第一个坑$arr[$i] ——一般取数组的第一个值,所以是$arr[$i]
            2、$j--; 先由后向前找比基准数小的数,找到后,挖出此数填在前一个坑$arr[$i]中.
            3、$i++; 再由前向后找比基准数大的数,找到后,挖出此数填在前一个坑$arr[$j]中.
            4、然后,重复执行2、3步,直到$i==$j.
            5、此时,已经结束对一个数组的调整,将$pivot的值填入留下的坑中$arr[$i]
        */    
            $i = $left;
            $j = $right;
            $pivot = $arr[$left];    //$arr[$i] = $arr[$left] 就是第一个坑
            $hole_idx = $left;    //保存当前坑的索引下标
    
            while ($i < $j) {
    
                //先从右边向左开始找小于pivot的数
                while ($i<$j && $arr[$j]>=$pivot) {    //如果找到小于$pivot的数,则停止循环!
                    $j--;
                }
                if ($i < $j) {
                    //将$arr[$j]填入$arr[$hole_idx]会形成一个新的坑
                    $arr[$hole_idx] = $arr[$j];
                    $hole_idx = $j;
                }
    
                //从左边向右找大于pivot的数
                while ($i<$j && $arr[$i]<=$pivot) {        //也可以使用 < 号    
                    $i++;
                }
                if ($i < $j) {
                    $arr[$hole_idx] = $arr[$i];
                    $hole_idx = $i;
                }
                $arr[$i] = $pivot;    //退出一次数组操作时,$i==$j,将$pivot填入这个坑中
            }
    
            //pivot已经放到了合适的位置,不需要再比较。所以是$i-1
            QuickSort($arr, $left, $i-1);    
            QuickSort($arr, $i+1, $right);
    }
    
    /*  
        与“挖坑填数”不太一样的另外一种方式:方法类似于冒泡排序的“两两交换”
        1、$i = $left; $j = $right;
        2、设置基准数,一般选取第一个
        3、从右边找到大于基准数的元素    
        4、从左边找到小于....
        5、交换这两个数(两两交换)
        6、重复 3-5 步操作
        7、执行完此操作后,把基准数和$arr[$i](或$arr[$j])交换
        8、递归执行
    
        因为快速排序的这种两两交换的思路比较相似,所以也有说这是冒泡排序的改进算法。
    */
        function QuickSort2( & $arr, $left, $right) {    // 使用数组引用
            
            if($right - $left <= 0) return 0;
    
            $i = $left;
            $j = $right;
            $pivot = $arr[$left];
    
            while ($j > $i) {    
                //先从右边向左开始找小于pivot的数
                while ($j>$i && $arr[$j]>=$pivot) {    // <=
                    $j--;
                }
                while ($j>$i && $arr[$i]<=$pivot) {    // >=
                    $i++;
                }
                if ($j > $i) {
                    $tmp = $arr[$i];
                    $arr[$i] = $arr[$j];
                    $arr[$j] = $tmp;
                }
            }
            $arr[$left] = $arr[$i];
            $arr[$i] = $pivot;        
            
            QuickSort2($arr, $left, $i-1);
            QuickSort2($arr, $i+1, $right);
        }    
    
    $arr = array(64, 64, 76, 19, 27, 123, 64, 56, 4, 64, 37, 8, 1);
    
    /*
    echo "<br/>";
    QuickSort2($arr, 0, 10-1);
    print_arr_values($arr);
    */
    
    QuickSort($arr, 0, count($arr)-1);    //N个元素的数组:0 ~ N-1
    print_arr_values($arr);
    
    function print_arr_values($ar) {
        echo "<br/>";
        foreach ($ar as $key => $value) {
            echo "<strong style="font-size:22px;">", $value, 
                 "</strong>", "&nbsp;&nbsp;&nbsp;&nbsp;";
        }
    }

    参考:https://blog.csdn.net/MoreWindows/article/details/6684558

  • 相关阅读:
    scala的泛型浅析
    spark2.0的10个特性介绍
    spark2.0 DataSet操作的一些问题记录
    scala中ClassOf、asInstenceOf、isInstanceOf三个预定义方法分析
    Java 多线程与并发编程专题
    java nio入门
    MySQL索引优化详解
    shiro学习笔记-Subject#login(token)实现过程
    【转】线程八锁
    ReadWriteLock读写锁
  • 原文地址:https://www.cnblogs.com/lxpursue/p/9824242.html
Copyright © 2011-2022 走看看