从二进制搜索到3-ary搜索

时间:2016-01-16 11:50:33

标签: java algorithm

原因是因为3-ary Search比二进制搜索更不方便,因为在每次调用时,3-ary Search需要做两个对话,而二进制搜索只需要一个:因此3-ary花费2log 3 (n)和二进制log 2 (n)。这是一个众所周知的事实。

我有个主意。

有一种称为三元搜索的算法,允许在数组上找到函数 f 的最大值,前提是最大值只有一个。以下是Java代码:

    public static <T> int ternarySearch(T[] array, Function<T,Double> f){
        int l = 0, r = array.length,
                m1 = l + (r-l)/3,
                m2 = r - (r-l)/3,
                valutation;
        while( m1 != m2 )
            {
            valutation = f.apply(array[m1]).compareTo(f.apply(array[m2]));
            switch(valutation)
                {
                case -1:    {   r = m1;                 m1 = l + (r-l)/3;   m2 = r - (r-l)/3;   break;  }
                case  0:    {   l = m1;     r = m2;     m1 = l + (r-l)/3;   m2 = r - (r-l)/3;   break;  }
                case  1:    {   l = m2;                 m1 = l + (r-l)/3;   m2 = r - (r-l)/3;   break;  }
                }
            }       
        return m1;
    }

如果我们可以找到一个只有最多选择key的功能,如果那么方法compareTo()仅花费一个在数字之间面对,ternarySearch(array, f)的调用仅花费log 3 (n):小于二进制搜索。

现在,我的问题是:

  1. 我们如何选择这样的函数f
  2. 方法compareTo()的费用是否只有一个在数字之间?
  3. 我的想法是否正确?

1 个答案:

答案 0 :(得分:0)

数目:

  1. 只需使用标识函数f(x) = x来简化操作 - 尝试查找最适合值的函数会大大降低此搜索的适用性;身份函数而不是递减值(已排序)数组是一个很好的起点
  2. 不,费用 2 (见下文)
  3. 我不这么认为,原因如下:
  4. 这里有几点指示:

    • 三元搜索有可能过滤掉更多的数字(2/3而不是1/2)但只有1/3的时间(以及过滤时间的2/3)第3个空格)即使使用Integer.compareTo()确实需要比二进制搜索更多的比较
      请检查{{3} }
    • 按照您的想法,我们应该使用 N 来实现 N-ary 搜索,其效果优于二进制搜索增长 N 的回报,因为比较次数也会 N
    • 请在source code for Integer.compareTo() to see 2 comparisons happening.
    • 上查看几个答案