• 有序表查找


    折半查找/二分查找

    前提:线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须采用顺序存储。

    基本思想:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。

    int Binary_Search(int *a, int n, int key)
    {
        int low, high, mid;    /* 定义最低下标为记录首位 */
        low = 1;    /* 定义最高下标为记录末位 */
        high = n;
        while (low <= high)
        {
            mid = (low + high) / 2;    /* 折半 */
            if (key < a[mid])    /* 若查找值比中值小 */
                high = mid - 1;        /* 最高下标调整到中位下标小一位 */
            else if (key > a[mid])    /* 若查找值比中值大 */
                low = mid + 1;    /* 最低下标调整到中位下标大一位 */
            else    /* 若相等则说明mid即为查找到的位置 */
                return mid;
        }
        return 0;
    }

    插值查找

    改进后的二分查找

    int Binary_Search(int *a, int n, int key)
    {
        int low, high, mid;    /* 定义最低下标为记录首位 */
        low = 1;    /* 定义最高下标为记录末位 */
        high = n;
        while (low <= high)
        {
            mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]); /* 插值 */
            if (key < a[mid])    /* 若查找值比中值小 */
                high = mid - 1;        /* 最高下标调整到中位下标小一位 */
            else if (key > a[mid])    /* 若查找值比中值大 */
                low = mid + 1;    /* 最低下标调整到中位下标大一位 */
            else    /* 若相等则说明mid即为查找到的位置 */
                return mid;
        }
        return 0;
    }

    斐波那契查找

    斐波那契数列的一条性质:前一个数除以相邻的后一个数,比值无限接近黄金分割。

    算法思想:采用最接近查找长度的斐波那契数值来确定拆分点。

    举个例子来讲:现有长度为9的数组,要对它进行拆分,对应的斐波那契数列(长度先随便取,只要最大数大于9即可){1,1,2,3,5,8,13,21,34},不难发现,大于9且最接近9的斐波那契数值是f[6]=13,为了满足所谓的黄金分割,所以它的第一个拆分点应该就是f[6]的前一个值f[5]=8,即待查找数组array的第8个数,对应到下标就是array[7],依次类推;推演到一般情况,假设有待查找数组array[n]和斐波那契数组F[k],并且n满足n>=F[k]-1&&n < F[k+1]-1,则它的第一个拆分点middle=F[k]-1。

    int Fibonacci_Search(int *a, int n, int key)
    {
        int low, high, mid, i, k = 0;
        
        low = 1;    /*定义最低下标为记录首位 */
        high = n;    /*定义最高下标为记录末位 */
    
        while (n > F[k] - 1)    /* 计算n位于斐波那契数列的位置  数组F为斐波那契数列*/
            k++;
    
        for (i = n; i < F[k] - 1; i++)        /* 将不满的数值补全 */
            a[i] = a[n];
        
        while (low <= high) 
        {
            mid = low + F[k - 1] - 1;    /* 计算当前分隔的下标 */
            
            if (key < a[mid])    /* 若查找记录小于当前分隔记录 */
            {
                high = mid - 1;    /* 最高下标调整到分隔下标mid-1处 */
                k = k - 1;    /* 斐波那契数列下标减一位 */
            }    
            else if (key > a[mid])    /* 若查找记录大于当前分隔记录 */
            {
                low = mid + 1;    /* 最低下标调整到分隔下标mid+1处 */
                k = k - 2;    /* 斐波那契数列下标减两位 */
            }
            else
            {
                if (mid <= n)    /* 若相等则说明mid即为查找到的位置 */
                    return mid;
                else        /* 若mid>n说明是补全数值,返回n */
                    return n;
            }
        }
        return 0;
    }
  • 相关阅读:
    git 每次push和pull都需要提交密码
    git push时报错refusing to merge unrelated histories
    打包时,node内存溢出问题解决方法
    dva中roadhog版本升级后带来的问题及解决方法
    Android
    Python Model : glob 文件路径查找
    Tools info
    Python class
    Life Info
    Char 10 格式化及如何正确使用
  • 原文地址:https://www.cnblogs.com/nkqlhqc/p/9636441.html
Copyright © 2020-2023  润新知