比二分尋找法更好的,我的估算值尋找法

來源:互聯網
上載者:User

我們知道,對於有序資料序列進行尋找,二分尋找法效能是相當好的,時間效率達到O(Log2N),但該演算法其實還有些可以進行改進的地方。
普通的二分尋找法,直接通過折半的方式來對有序資料序列進行篩選,這種方法實際上不是十分有效。對於大多數的有序資料序列,通常分布都是比較均勻的,我們完全可以通過對資料的分布進行估算,找出合理位置,減少折半次數。
基於估算資料序列折點的方式進行尋找,在資料分布最好的情況下,與二分尋找法一樣,時間效率都是O(1), 但在最壞的情況下,與普通情況下,都有著比二分尋找法,更優越的情能。
以下是一個簡單的估算尋找法實現:
#include <cstdlib>
#include <iostream>

using namespace std;

//普通估演算法,沒有對分布不均勻的情況進行特殊處理
int fEval(int a[], int first, int last, int targe)
{
   int nDevValue = 0;
   nDevValue = (a[last] - a[first]) / (last - first);
   if ((a[last] - a[first]) % (last - first) != 0)
       ++nDevValue;
   int nDev = (targe - a[first]) / nDevValue;
   if (targe - a[first] < nDevValue)
       return first + nDev + 1;
   else
       return first + nDev;
}

//對分布不均勻的情況,進行了特殊(跳躍式)處理
int fEval2(int a[], int first, int last, int targe)
{
    int cValue = a[(first + last)/2];
    if (cValue > targe)
    {
        return fEval(a, first, (first + last)/2, targe);
    }
    else
    {
        return (first + last)/2 + fEval(a, (first + last)/2, last, targe);
    }
}

//普通二分尋找法
int fBin(int a[], int first, int last, int targe)
{
   return (first + last) / 2;
}

template<typename EVAL>
int Find(int a[], int first, int last, int targe, EVAL feval)
{
    int result = -1;
    int count = 0;
    int nEvalFirst = first;
    int nEvalLast = last;
    int nEvalMid = 0;
    while ((nEvalFirst < nEvalLast)
           && (a[nEvalFirst] <= targe)
           && (a[nEvalLast] >= targe))
    {
        nEvalMid = feval(a, nEvalFirst, nEvalLast, targe);
        if (targe == a[nEvalMid])
        {
            result = nEvalMid;
            break;
        }
        else if (nEvalMid != nEvalLast && targe > a[nEvalMid])
        {
            nEvalFirst = nEvalMid + 1;
        }
        else if (nEvalMid != nEvalLast && targe < a[nEvalMid])
        {
            nEvalLast = nEvalMid;
        }
        else
        {
            break;
        }
        ++count;
    }
    cout << count << "/n";
    return result;
};

int main(int argc, char *argv[])
{
    //最差情況
    int a[] = {1, 2, 3, 4, 5, 100, 400};
    cout << Find(a, 0, 6, 201, fBin) << "/n";
    cout << Find(a, 0, 6, 201, fEval) << "/n";
    cout << Find(a, 0, 6, 201, fEval2) << "/n";

    //最好情況
    int b[] = {1, 2, 3, 4, 5, 6, 7};
    cout << Find(b, 0, 6, 4, fBin) << "/n";
    cout << Find(b, 0, 6, 4, fEval) << "/n";
   
    //普通情況
    int c[] = {1, 4, 6, 10, 15, 17, 20, 26, 40, 45, 48, 50, 52, 57, 59, 63,
               68, 74, 78, 82, 85, 93, 96, 101, 105, 109, 112, 117, 120, 121,
               123, 129, 133, 136, 140, 145, 147, 151, 154, 160, 163, 167,
               170, 176, 179, 180, 183, 187, 188, 192, 194, 197, 201, 204,
               210, 211, 215, 217, 220, 223, 225, 228, 231, 233, 237, 240,
               245, 247, 248, 256, 258, 261, 263, 267, 269, 272, 275, 277,
               279, 282, 283, 285, 289, 294, 297, 300};
    cout << Find(c, 0, 85, 123, fBin) << "/n";
    cout << Find(c, 0, 85, 123, fEval) << "/n";
   
    system("PAUSE");
    return EXIT_SUCCESS;
}
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.