快速排序(QuickSort)--php实现

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ahaotata/article/details/83754573

快速排序使用分治策略(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));
展开阅读全文

没有更多推荐了,返回首页