我在网上学习Quicksort时发现了很多变种方法。
每次在#34;替换/交换Pivot位置"的阶段让我感到困惑。 左/右指针过后。
问题:每轮后用左/右指针位置替换枢轴。这就是问题所在。
抱歉,我找不到合适的例子,因为我无法解决问题。但是,如果有人有更好的例子以及 PHP代码吗?示例:[81,70,97,38,63,21,85,68,76,9,57,36,55,79,74,85,16,61,77,49,24] 采取支点:57
如果需要,可以采用此示例: https://ece.uwaterloo.ca/~cmoreno/ece250/quick-sort-complete-example.pdf
答案 0 :(得分:1)
尝试帮助您提出更易于理解的问题
考虑具有N个元素的数组的这种情况:
阶段1:选择一个支点。 (例如,随机索引或三分之一中值)
阶段2:将枢轴置于某个位置。例如,使用最后一个元素在pivot索引处交换值。 Pivot现在位于A[N-1]
第3阶段:将除枢轴(最后位置)以外的所有元素分开 - 较小的元素位于A[0]..A[l]
,较大的元素位于A[r]..A[N-2]
第4阶段:使用A[N-1]
A[r]
)
哪个阶段不明确?
问题1:是否必须通过在第一个/最后一个位置交换枢轴来设置枢轴?因为我没有在每个例子中找到它。它留在那里的一些地方,在第一轮后,用上/下指针交换位置。
如果您使用第一个或最后一个元素作为数据透视表,则无需交换它,否则必须进行交换。请注意,pivot = first是选择pivot的最简单方法,但最坏情况的概率太高 - 对于(几乎)排序的数组而言]
问题2:让我们讨论一下内存
QuickSort不需要额外的内存用于新阵列,它可以就地工作。递归实现需要在堆栈中占用一些内存(隐式)。
用A [r]替换枢轴意味着在第1轮之后的右(向下)指针位置,对吗?
是的,它在穿越过程中向下指针位置。注意 - 当枢轴在最后时用向下指针交换,但是当枢轴在开始时用向上指针交换。
阶段3它是如何分开的?
使用分区方案Wiki。考虑Hoare的分区 - 它更容易理解。
答案 1 :(得分:0)
Quicksort的PHP代码:(使用 Lomuto分区方案我认为)
<?php
$unsorted = array(43,21,2,1,9,24,2,99,23,8,7,114,92,5);
function quick_sort($array)
{
// find array size
$length = count($array);
// base case test, if array of length 0 then just return array to caller
if($length <= 1){
return $array;
}
else{
// select an item to act as our pivot point, since list is unsorted first position is easiest
$pivot = $array[0];
// declare our two arrays to act as partitions
$left = $right = array();
// loop and compare each item in the array to the pivot value, place item in appropriate partition
for($i = 1; $i < count($array); $i++)
{
if($array[$i] < $pivot){
$left[] = $array[$i];
}
else{
$right[] = $array[$i];
}
}
// use recursion to now sort the left and right lists
return array_merge(quick_sort($left), array($pivot), quick_sort($right));
}
}
$sorted = quick_sort($unsorted);
print_r($sorted);
?>
//RESULT: Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 5 [4] => 7 [5] => 8 [6] => 9 [7] => 21 [8] => 23 [9] => 24 [10] => 43 [11] => 92 [12] => 99 [13] => 114 )