找到四个中的两个最小值?

时间:2012-08-31 11:49:32

标签: c algorithm

所以,我有四个整数,我需要找出这四个中最低的两个。用C(或任何其他语言)最有效的方式是什么?

编辑:为了提高效率,我需要一个固定的实现,因为这是一项非常关键的操作,将会执行数千次。

7 个答案:

答案 0 :(得分:5)

这是使用sorting networks的有效实现:

inline void Sort2(int *p0, int *p1)
{
    if (*p0 > *p1)
    {
        const int temp = *p0;
        *p0 = *p1;
        *p1 = temp;
    }
}

inline void Sort4(int *p0, int *p1, int *p2, int *p3)
{
    Sort2(p0, p1);
    Sort2(p2, p3);
    Sort2(p0, p2);  
    Sort2(p1, p3);  
    Sort2(p1, p2);  
}

这只需要5次比较,最多只需5次掉期。您可以忽略p2,p3的结果。

请注意,对于性能关键型应用程序Sort2,可以在某些体系结构的一个或两个指令中实现不带分支。

答案 1 :(得分:3)

只需写一个循环并跟踪lowes 2值? 应该是最大O(2N),这是我认为最好的复杂性。

答案 2 :(得分:3)

最有效的方式?为了避免任何额外的步骤,我得到了这个(伪代码)。这将避免与其他更通用的解决方案(特别是那些不利于比较操作的传递性质的解决方案)进行任何不必要的比较。

请记住,这只是考虑效率,而不是完美的代码。

if a<=b:
  if b<=c:
    # c too big, which of b and d is smaller?
    if b<=d:
      return (a,b)
    else:
      return (a,d)
  else if b<=d:
    # a and c both < b, and b < d
    return (a,c)
  else:
    # b is > a, c and d. Down to just those three.
    if a<=c:
      if c<=d:
        # a < c < d
        return (a,c)
      else:
        # a and d both < c
        return (a,d)
    else if d<=a:
      # Both c and d < a
      return (c,d)
    else:
      # c < a < d
      return (a,c)
else:
  # b < a
  if a<=c:
    # c too big, which of a and d is smaller?
    if a<=d:
      return (a,b)
    else:
      return (b,d)
  else if a<=d:
    # b and c both < a, and a < d
    return (b,c)
  else:
    # a is > b, c and d. Down to just those three.
    if b<=c:
      if c<=d:
        # b < c < d
        return (b,c)
      else:
        # b and d both < c
        return (b,d)
    else if d<=b:
      # Both c and d < b
      return (c,d)
    else:
      # c < b < d
      return (b,c)

我认为这是5个比较的最差情况和3的最佳情况(显然,在不到3个比较中没有办法做到这一点)。

答案 3 :(得分:3)

你可以通过恰当的4次比较和最多4次交换来逃脱。

inline void swap(int* i, int* j) {
  static int buffer;
  buffer = *j;
  *j = *i;
  *i = buffer;
}

inline void sort2(int* a, int* s) {
  if (*s < a[1])
    swap(s,a+1);
  if (*s < a[0]) // it is NOT sufficient to say "else if" here
    swap(s,a);
}

inline void sort4(int* a) {
  sort2(a,a+2);
  sort2(a,a+3);
}

结果将是第一个坐到细胞,但请注意,这些细胞不一定排序!它们只是最小的元素。

答案 4 :(得分:2)

我会用它们制作一个数组,排序并取前两个值。

答案 5 :(得分:2)

您最多可以通过4次比较来完成它:

  • 比较第一对数字,让较小的数字为a1,较大的数字为a2
  • 比较第二对数字,让较小的数字为a3,较大的数字为a4
  • 如果a1&gt; = a4返回(a3,a4)
  • (现在我们知道a1&lt; a4)
  • 如果a3&gt; = a2返回(a1,a2)
  • (现在我们也知道a3&lt; a2)
  • return(a1,a3)

要确定这是真的,您可以检查所有可能的回报组合:

(a1,a2)(a1,a3)(a1,a4)

(a2,a3)(a2,a4)

(a3,a4)

答案 6 :(得分:0)

我认为您可以对数组进行排序并选择前两个元素。