1. 程式人生 > >快速排序(QuickSort)--php實現

快速排序(QuickSort)--php實現

快速排序使用分治策略(Divide and Conquer)來把一個序列分為兩個子序列。

原理:

從序列中挑出一個元素,作為"基準"(pivot)
把所有比基準值小的元素放在基準前面,所有比基準值大的元素放在基準的後面(相同的數可以到任一邊),這個稱為分割槽(partition)操作
對每個分割槽遞迴地進行步驟1~2,遞迴的結束條件是序列的大小是0或1,這時整體已經被排好序了

<?php
/**
 * 快速排序
 * 資料結構----------------陣列
 * 最差時間複雜度-----------每次選取的基準都是最大(或最小)的元素,導致每次只劃分出了一個分割槽,需要進行n-1次劃分才能結束遞迴,時間複雜度為O(n^2)
 * 最優時間複雜度-----------每次選取的基準都是中位數,這樣每次都均勻的劃分出兩個分割槽,只需要logn次劃分就能結束遞迴,時間複雜度為O(nlogn)
 * 平均時間複雜度-----------O(nlogn)
 * 空間複雜度--------------O(logn)
 * 穩定性-----------------不穩定
 */
 
$arr = [1, 3, 34, 2, 32, 2, 78, -43, 53, -35, 0];
$len = count($arr);
 
function Swap(&$arr, $i, $j)
{												
	$temp = $arr[$i];
	$arr[$i] = $arr[$j];
	$arr[$j] = $temp;
}
// 劃分
function Partition(&$arr, $left, $right)
{
	$pivot = $arr[$right];					// 每次都選擇最後一個元素作為基準
	$tail = $left - 1;						// tail為小於基準的子陣列最後一個元素的索引
	for ($i = $left; $i < $right; $i++) {	// 遍歷基準以外的其他元素
		if ($arr[$i] <= $pivot) {			// 把小與等於基準的元素放到前一個子陣列的末尾
			$tail++;
			if ($tail != $i) {
				Swap($arr, $tail, $i);
			}
		}
	}
	Swap($arr, $tail + 1, $right);			// 最後把基準放到前一個子陣列的後邊,剩下的子陣列即是大於基準的子陣列
	return $tail + 1;
}
 
function QuickSort(&$arr, $left, $right)
{
	if ($left >= $right)
		return;
	$pivot_index = Partition($arr, $left, $right);	// 基準的索引
	QuickSort($arr, $left, $pivot_index - 1);
	QuickSort($arr, $pivot_index + 1, $right);
 
	return $arr;
}
print_r(QuickSort($arr, 0, $len - 1));