我知道这个问题以前有人问过。我读过它们,但我仍然不确定我所理解的是否正确。
假设我们有一个[51,20,26,16,19,38,10,37,49]
数组。
首先,我们必须选择中位数作为支点(第一,最后和中间)。
[51,19,49]
从那以后,49是支点,我们把它移到后面。
接下来,分区子数组[51,20,26,16,19,38,10,37]
49。
因为51是第一个大于49的元素,37是第一个小于49的元素,所以我们交换它们。
[37,20,26,16,19,38,10,51]
^ ^
重复相同的步骤。
由于51是第一个大于49但其索引大于37的元素,因此我们将pivot与51交换。现在我们的数组如下所示:
[37,20,26,16,19,38,10,49,51]
现在49和51已经排序。
然后,我们再次从[37,20,26,16,19,38,10]
中选择pivot:[37,16,10]。
交换枢轴返回:[37,20,26,10,19,38,16]查找大于16的元素:37
寻找小于16的元素:10
交换
[10,20,26,37,19,38,16]
查找大于16的元素:20
寻找小于16的元素:10
自指数20
[10,16,26,37,19,38,20]
从这里,我将重复从查找中位数到分区的步骤。然而,我真的不确定这是否是正确的方法。抱歉,如果这是一篇冗长的文章,我试图尽可能具体地说明我的思考过程。有人能告诉我我做的是对的吗?
三的中位数和分区方案Lomuto或Hoare存在差异。对于Hoare分区方案,三个中位数通常排序为第一、中间、最后:
[51,20,26,16,19,38,10,37,49] => [19,20,26,16,49,38,10,37,51]
霍尔从左向右扫描。左边没有值
[19,20,26,16,37,38,10,49,51]
左扫继续,直到再次达到49。右扫停止在10。由于右索引现在
[19,20,26,16,37,38,10] [49,51]
请注意,Hoare仅保证左侧部分元素是
Lomuto方案通常只从左侧扫描,通常枢轴在右侧。3的中位数仍然可以像我上面展示的那样交换,除了它会导致第一个
[51,20,26,16,19,38,10,37,49] => [19,20,26,16,51,38,10,37] [49]
Lomuto然后从左侧扫描,使用两个索引,一个每次更新,另一个索引为每个元素更新
[19,20,26,16,38,10,37,51] [49]
然后支点与第一个元素交换
[20,26,16,19,38,10,37] [49] [51]
对于Lomuto方案,可以在不交换的情况下确定3的中位数,然后将3的中位数交换到最后一个位置,这将与问题相同。
[51,20,26,16,19,38,10,37,49] => [51,20,26,16,19,38,10,37] [49]
第一个分区步骤将导致:
[51,20,26,16,19,38,10,37] [49] => [20,26,16,19,38,10,37] [49] [51]