首页 > 其他分享 >查找表

查找表

时间:2022-10-12 08:55:29浏览次数:39  
标签:折半 记录 ST 关键字 查找 key

查找表

查找表:是由同以类型的数据元素(或记录)构成的集合。由于"集合"中的数据元素之间存在着松散的关系,因此查找表是一种应用灵便的结构

什么查找?

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

  • 关键字: 用来标识一个数据元素(或记录)的某个数据项的值。

主关键字: 可唯一地标识一个记录的关键字是主关键字;

次关键字: 反之,用以识别若干记录的关键字是次关键字。

查找的结果

  • 查找结果给出整个记录的信息,或指示该记录的在查找表中的位置
  • 查找不成功:给出"空记录"或"空指针"

查找表分类

  • 静态查找表
    仅作"查询"(检索)操作的查找表
    *动态查找表
    作"插入"和"删除"操作的查找表
    有时在查询之后,还需要"查询"结果为"不在查找表中"的数据元素插入到查找表中;或者,从查找表中删除其查询结果为在查找表中的数据元素
    ,此类表为动态查找表

查找算法的评价指标

关键字的平均比较次数,也称平均查找长度
ASL(Average Search Length)

线性表的查找

顺序查找(线性查找)

  • 顺序表或线性链表表示的静态查找表
  • 表内元素之间无序
    顺序表的表示:
    数据元素类型定义
typedef struct{
 KeyType key;//关键子域
  ....//其他域
}ElemType;
typeder struct{
    ElemType *R ;//表基址
    int length;//表长
}SSTable;//SequentialSeearch Table

SSTable ST; //定义顺序表ST

伪代码

匹配

int Search_Seq(SSTable ST, KeyType key)
{
  //若成功返回其位置信息,否则返回0
  for(i=ST.length;i>=1;--i)
  {
   if(ST.R[i].key == key)
   return i;
  }
  return 0;
}
int Search_Seq(SSTableST,KeyType key)
{

 for(i=ST.length;ST.R[i].key!=key;--i)
  if(i<=0)break;
  if(i>0) return i;
  else return 0;
}

改进:把待查关键字key存入表头("哨兵"、"监视哨")从后往前逐个比较,可卖你去查找过程中每一步都要检测是否查找完毕,加快速度。

设置监视哨的顺序查找

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

当ST.length较大时,此改进能使进行一次查找所需的平均时间几乎减少一半
比较次数与key位置有关:

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

思考

  1. 记录的查找概率不相等时如何提高查找效率
  • 查找概率越高,比较次数越少。
  • 查找概率越低,比较次数较多。
  1. 记录的查找概率无法测定时如何提高查找效率
  • 方法-----在查找概率动态调整记录顺序:
    (1)在每个记录中设一个访问频度域
    (2)始终保持记录按非递增有序的次序排列
    (3)每次查找后均将刚查到的记录直接移到表头

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

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

折半查找算法(非递归算法)

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

折半查找算法

int Search_Bin(SSTable ST,KeyType key)
{
  int low =1;
  int high =ST.length;
  int mid = (low+high)/2
   while(low<=high)
   {
    if(ST.R[mid].key == key)
    return mid;//找到待查元素
    else if(key<ST.R[mid].key)//缩小查找区间
         high = mid-1; //继续在前半个区间进行查找
    else
        low = mid+1;//继续在后半区间进行查找
  }
return 0;//顺序表中不存在待查元素
}Serach_bin

折半查找的性能-判定树



比较次数 = 路径上的结点数
比较次数 = 结点的层数
比较次数<=树的深度(log2n)+1


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

分块查找(索引顺序表的查找)

  • 将表分成几块,且表或者有序,或者分块有序
    若i<j,则第j块中所有记录的关键字均大于第i块中的最大关键字。
  • 建立"索引表"(每个结点含有最大关键字域和指向本块第一个结点的指针,且关键字有序)

分块查找性能分析

查找效率:ASL = Lb+Lw
Lb对索引表查找的ASL,lw对块内查找的ASL
![](/i/l/?n=22&i=blog/2069956/202210

/2069956-20221012083619536-2073315541.png)

分块查找优缺点

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

查找方法比较

标签:折半,记录,ST,关键字,查找,key
From: https://www.cnblogs.com/doubleconquer/p/16782970.html

相关文章