您的位置:首页 > 其它

折半查找的优化版本

2015-11-02 20:32 501 查看
优化后的"折半查找"算法比标准"折半查找"执行次数要少, 少多少, 要看数据样本.



/// @file exam_1_1.c
/// @brief 折半查找的优化版

#include <stdlib.h>
#include <stdio.h>
#include <crtdbg.h>

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif

#ifndef OUT
#define IN
#define OUT
#endif

/// @name BisearchOpt
/// @brief 折半查找的优化版
/// @param IN int aryInt[], 要分析的数组
/// @param IN int iArySize, 数组容量
/// @param IN int iObj, 要在数组中找的目标元素
/// @param OUT int* piObjIndex, 找到的目标在数组中的位置索引
/// @param OUT int* piExecuteCnt 返回的执行次数
/// @return 是否找到了目标
BOOL BisearchOpt(
    IN int aryInt[],
    IN int iArySize,
    IN int iObj,
    OUT int* piObjIndex,
    OUT int* pExecuteCnt);

int main(int argc, char** argv)
{
    BOOL bRc = FALSE;
    int iExecuteCnt = 0;
    int iObjIndex = -1;
    int aryInt[10] = {1, 992, 993, 994, 995, 996, 997, 998, 999, 1000};

    bRc = BisearchOpt(
        aryInt, 
        sizeof(aryInt) / sizeof(int), 
        992, 
        &iObjIndex, 
        &iExecuteCnt);
    
    printf("BisearchOpt %s, iObjIndex = %d, iExecuteCnt = %d\n",
        bRc ? "success" : "fail", 
        iObjIndex, 
        iExecuteCnt);
    
    /** run result
    BisearchOpt success, iObjIndex = 1, iExecuteCnt = 2
    */

    printf("END, press any key to quit\n");
    getchar();
    return 0;
}

BOOL BisearchOpt(
    IN int aryInt[],
    IN int iArySize,
    IN int iObj,
    OUT int* piObjIndex,
    OUT int* pExecuteCnt)
{
    /// aryInt[10] = { 1, 992, 993, 994, 995, 996, 997, 998, 999, 1000}

    BOOL bRc = FALSE;
    int i = 0;
    int iTmp = 0;
    int iL = 0;
    int iR = iArySize - 1;
    int iM = (iR - iL) / 2;
    float fRate = .0f;

    _ASSERT(NULL != piObjIndex);
    _ASSERT(NULL != pExecuteCnt);

    *piObjIndex = -1;
    *pExecuteCnt = 0;

    do 
    {
        ++(*pExecuteCnt);
        if (iR < iL)
        {
            break; ///< 查找失败, 参数错
        }
        else if ((iL == iM) && (iM == iR))
        {
            *piObjIndex = iL;
            bRc = TRUE; ///< 找到
            break;
        }
        else if ((aryInt[iL] == iObj) 
            || (aryInt[iR] == iObj) 
            || (aryInt[iM] == iObj))
        {
            bRc = TRUE;

            if (aryInt[iL] == iObj)
            {
                *piObjIndex = iL;
            }

            if (aryInt[iR] == iObj)
            {
                *piObjIndex = iR;
            }

            if (aryInt[iM] == iObj)
            {
                *piObjIndex = iM;
            }

            break; ///< 目标刚好在LRM上, 找到
        }
        else if ((iR - iL) <= 3)
        {
            /// 最后几个数据, 顺序查找
            for (i = 0; i <= 3; i++)
            {
                if (aryInt[iL + i] == iObj)
                {
                    *piObjIndex = (iL + i);
                    bRc = TRUE; ///< 找到    
                }
            }

            break; ///< 这是最后一个数据了, 找了一圈了
        }

        /// 在查找之前,调整M
        fRate = 1.0f * iObj / (aryInt[iR] - aryInt[iL]);
        iM = (int)((iR - iL) * fRate);

        iTmp = aryInt[iM];
        if (iTmp < iObj)
        {
            /// 在右半段继续查找
            iL = iM;
            iR--;
        }
        else if (iTmp > iObj)
        {
            /// 在左半段继续查找
            iR = iM;
            iL++;
        }

        iM = (int)(1.0f * (iR - iL) / 2);
    } while (1);

    return bRc;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: