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

    快速排序


    一、简介:

    快速排序(Quicksort)是对冒泡排序的一种改进。
    它的基本思想是:

      通过一趟排序将要排序的数据分割成独立的两部分,
      其中一部分的所有数据都比另外一部分的所有数据都要小,
      然后再按此方法对这两部分数据分别进行快速排序,
      整个排序过程可以递归进行,
      以此达到整个数据变成有序序列。

    算法稳定性: 不稳定排序算法。


    二、代码示例:

    第一种,笨方法,根据基本思想,递归左右分割数组,但这样太浪费空间:

    /**
     * 快速排序
     * @param  array  $arr 数组
     * @param  boolean $asc 是否升序
     * @return array
     */
    function quick_sort($arr){
        if(!is_array($arr)){
            return [];
        }
        $len = count($arr);
        if($len <= 1){
            return $arr;
        }else if($len == 2){
            if($arr[0]>$arr[1]){
                return array($arr[1],$arr[0]);
            }else{
                return $arr;
            }
        }
        $left_arr = [];
        $right_arr = [];
        $middle_value = $arr[0];//标尺选择第一个元素
        for ($i=1; $i < $len; $i++) { 
            if($arr[$i]<$middle_value){
                $left_arr[] = $arr[$i];
            }else{
                $right_arr[] = $arr[$i];
            }
        }
        $left = quick_sort($left_arr);
        $right = quick_sort($right_arr);
        return array_merge($left,array($middle_value),$right);
    }

    第二种,精巧的方式:

    (左指针、右指针同时向中间移动,不定义新的数组,就不消耗额外的空间,使用引用传值,注意会改变原有变量)

    /**
     * 快速排序
     * @param  [type]  &$arr  数组
     * @param  integer $begin 开始位置
     * @param  [type]  $end   结束位置
     * @return [type]         null
     */
    function quick_sort(&$arr,$begin=0,$end=null){
        if(!is_array($arr)){
            return;
        }
        $len = count($arr);
        if($len <= 1){
            return;
        }
        if($end === null){
            $end = $len - 1;
        }
        if($end - $begin <= 1){
            return;
        }
        $value = $arr[$begin];//以第一个为标尺值
        $right_to_left = true;//是否从右到左
        $p1 = $begin;//左侧指针
        $p2 = $end;//右侧指针
        while($p1<$p2){
            if($right_to_left){
                //从右侧开始,每项与标尺值比较,
          //若比标尺值小,则把值放到前边,然后换循环方向,从左侧开始
                for ($i=$p2; $i>$p1; $i--) { 
                    if($arr[$i]<=$value){
                        $arr[$p1++] = $arr[$i];
                        $right_to_left = false;
                        $p2 = $i;
                        continue 2;
                    }
                }
                $p2 = $p1;
            }else{
                //从左侧开始,每项与标尺值比较,
                //若比标尺值大,则把值放到前边,然后换循环方向,从右侧开始
                for ($i=$p1; $i < $p2; $i++) { 
                    if($arr[$i]>=$value){
                        $arr[$p2--] = $arr[$i];
                        $right_to_left = true;
                        $p1 = $i;
                        continue 2;
                    }
                }
                $p1 = $p2;
            }
        }
        $arr[$p1] = $value;
        quick_sort($arr,$begin,$p1-1);
        quick_sort($arr,$p1+1,$end);
    }


  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/gyfluck/p/10571889.html
Copyright © 2011-2022 走看看