数据结构与算法---查找(线性表)

本文介绍了查找表的概念,区分了静态和动态查找表,并详细探讨了顺序查找(包括线性查找和改进后的顺序查找)、折半查找以及分块查找(索引顺序查找)的方法。重点分析了它们的时间效率和空间复杂度,以及适用场景。
摘要由CSDN通过智能技术生成
以下内容主要参考青岛大学王卓老师的数据结构与算法基础。https://www.bilibili.com/video/BV1nJ411V7bd?p=137&vd_source=f893624050c1893c80cd53fcdcf62cfe

查找的基本概念

        在哪查?    ---查找表

        查找表是同一类型的数据元素构成的集合。

        什么查找? 

        根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素或记录。

  •          主关键字:唯一标识一个记录的关键字(比如准考证号)
  •          次关键字:用于识别若干记录的关键字(比如姓名(存在同名))

        查找成功否?

        根据给定的某值,在查找表中确定其关键字等于给定值的数据元素或记录。若存在,则称“查找成功”,查找结果给出整个记录的信息或在查找表中的位置,否则称“查找失败”,结果给出空记录空指针

        查找表的分类?

                静态查找表:仅作“查询”操作的查找表。

                动态查找表:“插入”“删除”操作的查找表。


线性表的查找

一、顺序查找(线性查找)

        应用范围

  •          顺序表线性链表表示的静态查找表
  •           表内元素之间无序

        顺序表的表示

        数据元素类型定义

typedef struct{
    KeyType key;     //关键字域
        ...          //其他域
}ElemType;
typedef struct{      //顺序表结构类型定义
    ElemType *R;     //表基址
    int len;         //表长
}SSTable;
SSTable ST;

        在顺序表ST中查找值为key的数据元素

        eg:在ST中查找13,找到,返回“5”.查找60,未找到,返回“0”.

        算法1实现

int Search_Seq(SSTable ST,KeyType key)
{
    for(int i = ST.len; i >= 1; --i)
        if(ST.R[i].key == key) 
            return i;
    return 0;
}

          算法2实现

int Search_Seq(SSTable ST,KeyType key)
{
    for(int i = ST.len; ST.R[i].key != key; --i)
        if(i <= 0) break; 
    if(i > 0 ) return i;
    else return 0;
}

        算法3实现

int Search_Seq(SSTable ST,KeyType key)
{
    for(int i = ST.len; ST.R[i].key != key && i > 0; --i);
    if( i > 0 ) 
          return i;
    else  
        return 0;
}

        改进---监视哨

        在待查关键字key存入表头(“哨兵”、“监视哨”),从后往前逐个比较,可免去查找过程中每一步都要进行检测是否查找完毕,加快速度。---不用考虑是否越界

        eg:查找“60”,在表头存入“60”,称为“哨兵”。

        算法4实现:

int Search_Seq(SSTable ST,KeyType key)
{
    ST.R[0].key = key;
    for(int i = ST.len; ST.R[i].key != key; --i);
    return i;
}

        当ST.len较大时,此改进能使进行一次查找所需的平均时间几乎减少一半。

        时间效率分析  

        比较次数与key位置有关:

  •           查找第i个元素,需要比较n-i+1次
  •            查找失败,需比较n+1次

         时间复杂度O(n):

                查找成功时的平均查找长度,设表中个记录查找的概率相等

  ASLs(n)=(1+2+...+n)/n=(n+1)/2

        空间复杂度:  一个辅助空间------O(1)


二、折半查找法(二分或对半查找)

        折半查找:每次将待查记录所在区间缩小一半。

        查找算法:

        设表长为n,  low、high和mid分别指向待查元素所在区间的上界、下界和中点,key为给定的要查找的值:

        初始时,令low=1, high=n, mid=向下取整[(low+hhigh)/2]

        设k与mid指向的记录比较

                若key==R[mid].key, 则查找成功

                若key<R[mid].key, 则high=mid-1

                若key>R[mid].key, 则low=mid+1

        重复上述操作,直到low>high时,查找失败。

        算法1实现:

int Search_Bin(SSTable ST,KeyType key)
{
    low = 1; high = ST.len;               //设置区间初值
    while(low <= high){                   
        mid = (low +high) / 2;
        if(ST.R[mid].key == key) 
            return mid;                   //找到待查元素
        else if(key < ST.R[mid].key)      //缩小查找区间
            high = mid - 1;               //在前半段区间查找
        else
            low = mid + 1;                //在后半段区间查找
    }
    return 0;                             //不存在此元素
}

        算法2实现:(递归算法)

int Search_Bin(SSTable ST,KeyType key, int low ,int high)
{
    if(low > high)    return 0;                  
        mid = (low +high) / 2;
    if( key == ST.elem[mid].key) 
        return mid;                   
    else if(key < ST.elem[mid].key) 
            return mid;                  
     .....//递归,在前半段去检查找

    else ...  //递归,在后半段区间查找            
    
    return 0;                             
}

        折半查找的性能分析---判定树

        查找成功        

  •         比较次数 = 路径上的结点数
  •         比较次数 = 结点的层数
  •         比较次数 <=  树的深度 = 向下取整【log2 n】+ 1

        查找不成功

                比较次数 = 路径上的内部节点数

        顺序查找为平均长度为6二分法查找平均长度为3 .

        优缺点:

  •         优点:效率比顺序查找高
  •         缺点:只适用有序表,且限于顺序存储结构(对线性链表无效)

三、分块查找(索引顺序查找)

         查找过程:先确定待查记录所在的块(顺序或折半查找),再在块内查找(顺序查找)。

         条件:

                将表分成几块,且表有序或者分块有序(第二块的元素都大于第一块的最大值);

                建立索引表

        eg:假设要查找的元素为38

                通过索引表,38在第二块上,在第二块进行顺序查找

        分块查找性能分析

               查找效率: 

 ASL= Lb + Lw

  •                 Lb:   对索引表查找的ASL    
  •                 Lw:对块内查找的ASL

        eg: 当n=9,s=3时,ASLbs = 3.5,而折半法为3.1,顺序法为5

        优缺点

  •            优点:插入和删除比较容易,无需大量的移动
  •            缺点:要增加一个索引表的存储空间并对初始索引表进行排序运算。
  •            适用情况:如果线性表既要快速查找又经常动态变化,则采用分块查找。

    查找方法比较

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值