6.1 查找算法_基础

作者: 个革马 | 来源:发表于2017-04-29 16:09 被阅读44次

    1. 查找基本概念

    • 查找:只有两种情况,查找成功,查找失败
    • 查找表:查找的数据集合称为查找表
    • 静态查找表 / 动态查找表:区别在于是否只进行查找,还是需要插入,删除处理。
    • 平均查找长度:ASL = P1C1 + P2C2 + ... +PnCn
      P是查找到第 i 个元素的概率,一般认为 P = 1 / n
      C是查找到第 i 个元素的比较次数。

    2. 顺序查找

    暴力查找,直接从头开始逐个比较,直到找到或者遍历完为止。
    值得注意的是哨兵设置,通过哨兵,知道已遍历完。

    int Search_Seq(SSTable ST, elemType key)
    {
        //设置哨兵
        ST.elem[0] = key;
        // i 指向表的最后,逐个比对,如果没有最后肯定会返回 0 
        for (i = ST.TableLen; ST.elem[i] != key; --i) ; 
        return i;
    }
    

    以上是查找非顺序表的代码,当查找顺序表的时候也是通过逐个比对,但是若发现此时a[i] > key 则表明表中没有该关键字,可以退出循环。

    3. 折半查找(二分查找)

    • 基本思路:和序列中间值mid比对,如果key > mid则从右边序列找,如果key < mid 则从右边序列找。在子序列中依旧按照如此法则。
    int Binary_Search(SeqList l, elemType key)
    {
        int low = 0,high = length,mid;
    
        while (low <= high)
        {
            mid = (low + high) / 2;
            if(l.elem[mid] == key)
                return mid;
            else if(l.elem[mid] > key)  //调整high或low的位置,把查找的范围缩小到一半
                high = mid - 1;
            else 
                low = mid + 1;
        }
    
        return -1;
    }
    
    • 由于算法的特性,可以把数据存储在二叉排序树中,称为判定树。
      其中,除叶子节点外每个节点存储一个关键字,大于其左孩子,小于其右孩子。其中叶子节点存储的是查找不成功的情况。

    ASL = 1/n * (1 * 1 + 2 * 2 + ... + h * 2h - 1) = (n + 1)/n * log2(n + 1) - 1
    每一层的查找路径长度为h,每一层有2h - 1个节点

    4. 分块查找

    基本思路:把记录分为多个块,每个块之中的记录是无序的,但是,块与块之间有序。前面块的最大关键字,要小于后面块的最小关键字。

    由此可分析出,查找分为了两个步骤:

    1. 索引查找:按顺序与块的最大关键字做比较,若小于其最大关键字,则找到块
    2. 块内查找

    ASL = Lb(索引查找) + Ls(块内查找)

    相关文章

      网友评论

        本文标题:6.1 查找算法_基础

        本文链接:https://www.haomeiwen.com/subject/hxuugttx.html