我有一个看起来像这样的数组:
int array[] = {4.53, 3.65, 7.43, 9.54, 0.72, 0.0}
我只是想知道我可以使用什么方法对数组进行部分排序,以将前三位最大的双打带到前面。我正在寻找最有效的方法来获取此数组中的前三个最高数字。
到目前为止,我一直在使用qsort
,但是我只是在寻找另一种方法来执行此操作,它可能甚至更快。我知道这qsort
是O(nlogn)
最好的情况,O(n^2)
最坏的情况,但是有没有更有效的方法来解决此问题?我所说的高效只是比它更好的一种更快的方法O(nlogn)
。
任何帮助都会很棒
只需保持第一,第二,第三。
first = array[0];
second = array[1];
third = array[2];
/* scratch sort for three elements */
if(first < second)
swap(first, second);
if(first < third)
swap(first, third);
if(second < third)
swap(second, third);
/* now go through, bubbling up if we have a hit */
for(i=3;i<N;i++)
{
if(third < array[i])
{
third = array[i];
if(second < third)
{
swap(second, third);
if(first < second)
swap(first, second);
}
}
}
我不会尝试扩大到k = 4。我认为三个是对其进行硬编码的限制。随着k变大,您需要使用一种正式方法。
这不能回答您实际提出的问题,即如何进行部分排序,但这似乎是您想要的。
如果您希望部分排序,则可以使用快速排序,并且只要枢轴超出您感兴趣的范围,就可以早点返回。因此,我们的第一个枢轴分为五个,两个。忽略最后两个,而实际上只执行最后五个的子分类。但是,尽管它比quicksort更快,但它不会改变游戏规则。如果您可以在第k个项目上获得一个保守的上限(例如,最小值和平均值之间的最大值始终为25%),则可以快速消除大部分数据。如果您弄错了,那只是一两遍。
使用快速排序方法
int sortfirstk_r(int *array, int N, int k)
{
int pivot = 0;
int j = n -1;
int i = 1;
while(i <= j)
{
if(array[pivot] < array[i])
swap(array[i], array[j--])
else
i++;
}
sortfirstk_r(array, i, k < i ? k : i);
if(i < k)
sortfirstk_r(array +i, N -i, k - i);
}
(未经测试,排序逻辑可能有些棘手)。
但是,我们天真的使用第一个元素作为枢轴。如果我们正在对大型数据集进行排序,并且它具有正态分布,并且我们希望前1%,则z得分为2.326。再花一点点让我们有一些采样误差,然后我们进行一次通过,将枢轴设置为比平均值高2.3个标准偏差。然后,我们将分布分为两组,顶部1%加一点,其余部分。我们不需要进一步处理其余部分,只需对最上面的一组进行排序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句