考研复习之数据结构笔记(十三)查找(上)(概念与静态查找,顺序查找、折半查找、分块查找)

目录

一、基本概念

1.1 相关概念

1.2 分类与算法评价

二、顺序查找

三、折半查找

3.1 经典折半查找

3.2 静态数表查找

四、分块查找


一、基本概念

1.1 相关概念

查找表:由同一类型的数据元素(或记录)构成的集合
查找:也叫检索,是根据给定的某个值,在表中确定一个关键字等于给定值的记录或数据元素
关键字:是数据元素中某个数据项的值,它可以标识一个数据元素

对查找表经常进行的操作:

  •  查询某个“特定的”数据元素是否在查找表中;
  •  检索某个“特定的”数据元素的各种属性;
  • 在查找表中插入一个数据元素;
  • 从查找表中删去某个数据元素

1.2 分类与算法评价

查找表可分为两类:

静态查找表——仅作查询和检索操作的查找表;
动态查找表——在查找过程中同时插入不在查找表中的数据元素,或者删除在查找表中存在的数据元素。

查找方法评价:

  •  查找速度
  •  占用存储空间多少
  •  算法本身复杂程度
  •  平均查找长度ASL(Average Search Length):为确定记录在表中的位置,需要与给定值进行比较的次数的期望值叫查找算法的~

 图1.2-1 平均查找长度ASL

静态查找表的查找方法有顺序查找、折半查找、散列查找等;适合动态查找表的查找方法有二叉排序树的查找、散列查找(哈希表)等。二叉平衡树和B树都是二叉排序树的改进。

二、顺序查找

 查找过程:从表的一端开始逐个进行记录的关键字和给定值的比较
 适用条件:以顺序表或线性链表表示的静态查找表

 图2.1-1 查找过程

代码实现如下:

int Search_Seq( SSTable ST, KeyType key)
{  
   int i;
   ST.elem[0].key=key;//设置”监视哨”
   for(i=ST.length;ST.elem[i].key!=key;i--)
        ;
   return(i);
}
//查找成功——返回元素下标查找失败——返回0

  图2.1-2 平均查找长度

 优点:算法简单,对表的逻辑次序和存储结构无要求
 缺点:平均查找长度较大

  图2.1-3 减少平均查找长度的方式

三、折半查找

3.1 经典折半查找

 查找过程:每次将待查记录所在区间缩小一半
 适用条件:采用顺序存储结构的有序静态查找表
 算法实现:

  1. 设表长为n,low、high和mid分别指向待查元素所在区间的下界、上界和中点,k为给定值
  2. 初始时,令low=1,high=n,mid=(low+high)/2向下取整。
  3. 将mid指向的记录与k比较(假设有序表升序)
    若k==r[mid].key,查找成功
    若k<r[mid].key,则high=mid-1
    若k>r[mid].key,则low=mid+1
  4. 重复上述操作,直至找到记录,查找成功;或low>high,查找失败

 图3-1 折半查找演示

int  Search_Bin( SSTable ST, KeyType k)
{  int low,high,mid;
   low=1;  high=ST.length;
   while(low<=high)
   {  mid=(low+high)/2;
      if(k>ST.elem[mid].key)  low=mid+1;
      else if(k==ST.elem[mid].key)  return mid;
      else   high=mid-1;
   }
      return(0);
}

  图3-2 折半查找算法分析

优点:平均查找长度较小,查找效率高于顺序查找
缺点:只适用于顺序存储的有序表,不适用于一般顺序表和链式存储结构

3.2 静态数表查找

在不等概率查找的情况下,折半查找不是有序表查找的最好方法。

 图3.2-1 折半查找存在部分问题

静态最优查找树:查找性能达最佳的判定树,即PH值为最小的二叉树

PH:带权内路径长度之和

其中:
n: 二叉树结点个数,即有序表长度;
hi :第i个结点在二叉树上层次数;
wi :结点的权值, wi =cpi ,c为常量,pi为结点查找概率

构建过程如下:

图3.1-2 静态最优查找树构造方法

 图3.1-3 静态最优查找树构造演示

四、分块查找

 查找过程:将线性表分成几块,块内无序,块间有序;先确定待查记录所在块,再在块内查找
 适用条件:分块有序表

索引顺序查找(分块查找)的过程也是一个“缩小区间”的查找过程。

 图4-1 分块查找算法实现

int Seach_Index(SSTable ST,IndexTable IT[ ],int b,int n,   
                             KeyType k)
{  int i=1,j;
   while((k>IT[i].MaxKey)&&(i<=b))  
          i++;
   if(i>b)
         {  printf("\nNot found");  return(0); }
   j=IT[i].FirstLink;      while((k!=ST.elem[j].key)&&(ST.elem[j].key<=IT[i].MaxKey)  
             &&(j<n))
           j++; 
   if(k!=ST.elem[j].key) 
         { j=0; printf("\nNot found"); }
   return(j);
}

 图4-2 分块查找的ASL

  图4-3 查找方法比较

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D了一天bug忘了编译

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值