在线性搜索和二进制搜索之间进行权衡

时间:2018-08-02 08:37:42

标签: binary-search linear-search tradeoff

我有一个可变长度数据集中要搜索的元素列表。我尝试过二进制搜索,但发现目标是搜索元素列表时并不总是很有效。

我进行了以下研究,并得出结论:如果要搜索的元素数量少于数据的5%,则二进制搜索是有效的,否则线性搜索会更好。

下面是详细信息
元素数:100000
要搜索的元素数:5000
迭代次数(二进制搜索)= log2 (N) x SearchCount=log2 (100000) x 5000=83048

与线性搜索相比,搜索元素数量的进一步增加导致更多的迭代。

对此有何想法?

仅当要搜索的元素数小于5%时,我才调用以下函数。

       private int SearchIndex(ref List<long> entitylist, ref long[] DataList, int i, int len, ref int listcount)
    {
            int Start = i;
            int End = len-1;
            int mid;

            while (Start <= End)
            {
                mid = (Start + End) / 2;


                long target = DataList[mid];

                if (target == entitylist[listcount])
                {
                    i = mid;
                    listcount++;
                    return i;
                }
                else
                {
                    if (target < entitylist[listcount])
                    {
                        Start = mid + 1;
                    }

                    if (target > entitylist[listcount])
                    {
                        End = mid - 1;
                    }
                }
            }
            listcount++;
            return -1; //if the element in the list is not in the dataset


    }

在代码中,我重新调整索引而不是值,因为我需要在调用函数中使用Index。如果i = -1,则调用函数会将值重置为上一个i,然后使用新元素再次调用该函数以进行搜索。

1 个答案:

答案 0 :(得分:1)

在您的问题中,您正在寻找N个长数组中的M个值,N> M,但是M可能会很大。

通常,这可以通过M个独立的二进制搜索来实现(甚至可以稍微优化一下以以前的结果为起点):您将转到O(M * log(N))。

但是,利用M个值也被排序的事实,您可以通过线性搜索一次性找到所有它们。在这种情况下,您将遇到问题O(N)。实际上,这比M大的O(M * log(N))好。

但是您还有第三个选择:由于对M个值进行了排序,因此也对M个值进行了二进制分割,并且每次找到它时,都可以将后续搜索限制在找到的索引左右两侧的范围内。

第一次查询是在所有N个值上,第二次是在(平均)N / 2上,而不是在N / 4数据上是4个,....我认为这个标度为O(log(M) * log(N))。不确定,欢迎发表评论!

但是here is a test code-我对您的代码做了些微修改,但未更改其功能。

如果您有M = 100000和N = 1000000,则“ M二进制搜索方法”大约需要进行180万次迭代,这比线性扫描N个值所需的1M迭代次数还要多。但是根据我的建议,它仅需要272K迭代。

即使M值非常“折叠”(例如,它们是连续的),并且线性搜索处于最佳状态(100K迭代就足以获取所有值,请参见代码中的注释) ,该算法的效果很好。