[英]Partition in Quickselect
我必须实现一个返回数组中位数的算法。 所以我选择实现 Quickselect,这似乎对此很有效,而且我看到对于三分区,我可以使用 Quicksort 中使用的相同分区算法。
我的讲义(C 代码)中报告的分区算法如下:
for (i = lo, j = hi;
(i <= j);)
{
while (a[i] < pivot)
{
i++;
}
while (a[j] > pivot)
{
j--;
}
if (i <= j)
{
if (i < j)
{
/* exchange values */
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
i++;
j--;
}
}
现在,如果我的数组是:a = [40, 20, 100, 60, 80] 并且我选择数字 80 作为主元,结果是:a = [40, 20, 80 , 60, 100],但是作为你可以看到右侧分区中的值并非全部 > 80(我们有 60)。 如果我选择任何其他数字,则算法正常工作。
这个算法有错吗?
提前谢谢你的帮助!
[40, 20, 100, 60, 80]
i ... #while (a[i] < pivot)
[40, 20, 100, 60, 80]
i j ... #while (a[j] > pivot)
[40, 20, 80, 60, 100]
i j ... #/* exchange values */
[40, 20, 80, 60, 100]
ij ... #i++;j--;
[40, 20, 80, 60, 100]
j i ... #while (a[i] < pivot)
[40, 20, 80, 60, 100] ... exit for-loop .. finish
对于快速选择,您需要使用递归算法来找到枢轴元素的正确位置,从而将整个数组分成两半 [枢轴位置右侧的元素的值小于枢轴,左侧的元素的值小于枢轴位置枢轴位置的价值大于枢轴]
您的算法不考虑在第一个循环结束后应该做什么。 它只找到第一个选择的枢轴元素的位置(这太错误了)。 如果找到的枢轴位置不是中间位置(选定的枢轴不是中位数)会发生什么?
然后它应该移动到左侧部分(如果新发现的枢轴元素的位置大于中间位置)否则它应该移动到右侧部分,并再次执行上述步骤。
如果你什么都不明白,请发表评论
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.