<?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>", " ";
}
}
参考:https://blog.csdn.net/MoreWindows/article/details/6684558