快速排序是一种高效的排序算法,它基于分治法的思想,通过递归地将数据集分成更小的部分来实现排序。快速排序算法的核心思想是选择一个基准值(pivot),然后将数组分为两部分:一部分是小于基准值的元素,另一部分是大于基准值的元素。这个过程会递归地在这两部分上重复进行,直到整个数组被排序。
快速排序算法由C. A. R. Hoare在1960年提出。它是一种非常简洁且优雅的算法,其基本步骤如下:
快速排序算法的效率在很大程度上取决于基准值的选择。如果每次都选择列表中的最大值或最小值作为基准值,那么算法的性能将大大降低。在最坏的情况下,快速排序的性能可能与冒泡排序和插入排序相当。然而,在实际应用中,使用随机生成的列表时,快速排序很少会遇到最坏情况。
理想情况下,基准值应该是列表的中间元素,这样可以将列表平均分成两个子列表。然而,直接获取列表的中间元素并不是一个简单的过程,这可能会降低算法的效率。因此,通常选择列表的第一个元素或最后一个元素作为基准值。
选择基准值后,接下来的步骤就相对简单了。将所有大于基准值的元素放到右侧,将所有小于基准值的元素放到左侧。然后,递归地对左右两个子列表进行相同的操作。
快速排序算法的实现通常有两种方式:递归实现和迭代实现。递归实现是最直接的方式,因为它遵循了分治法的原则。在每一步中,将列表分成两部分,并将这两部分作为子列表传递给递归函数。然而,递归实现可能会消耗较多的内存,因此迭代实现也是一个可行的选择。迭代实现通常使用额外的内存来模拟递归过程,例如使用栈。
在PHP中,递归实现快速排序的代码如下:
<?php
$list = array(5,3,9,8,7,2,4,1,6,5);
function quicksort($array) {
if (count($array) == 0) {
return array();
}
$pivot = $array[0];
$left = $right = array();
for ($i = 1; $i < count($array); $i++) {
if ($array[$i] < $pivot) {
$left[] = $array[$i];
} else {
$right[] = $array[$i];
}
}
return array_merge(quicksort($left), array($pivot), quicksort($right));
}
print_r(quicksort($list));
?>
在PHP中,迭代实现快速排序的代码如下:
<?php
$list = array(5,3,9,8,7,2,4,1,6,5);
function quicksort_iterative($array) {
$stack = array($array);
$sorted = array();
while (count($stack) > 0) {
$temp = array_pop($stack);
if (count($temp) == 1) {
$sorted[] = $temp[0];
continue;
}
$pivot = $temp[0];
$left = $right = array();
for ($i = 1; $i < count($temp); $i++) {
if ($pivot > $temp[$i]) {
$left[] = $temp[$i];
} else {
$right[] = $temp[$i];
}
}
$left[] = $pivot;
if (count($right))
array_push($stack, $right);
if (count($left))
array_push($stack, $left);
}
return $sorted;
}
print_r(quicksort_iterative($list));
?>
快速排序的平均时间复杂度为O(n*log(n)),与归并排序相同。然而,在最坏的情况下,其时间复杂度为O(n^2),与冒泡排序相同。最坏情况通常发生在列表已经排序,而总是选择列表的最后一个元素作为基准值时。但在实践中,很少会遇到需要再次排序的已排序列表。
快速排序是一种非常优秀的排序算法,开发者通常会选择使用它。以下是快速排序的一些优缺点: