快速排序
快速排序
一、简介:
快速排序(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); }