[数据结构复习]查找

本文详细介绍了数据结构中的查找技术,包括顺序查找、折半查找、索引顺序查找、树表查找(如二叉排序树和平衡二叉树)以及散列表。重点讨论了各种查找方法的优缺点、实现细节和性能分析,如二叉排序树的查找效率与树的形状有关,平衡二叉树确保查找效率维持在O(logn)。对于散列表,讲解了散列函数设计原则和冲突处理方法,如开放定址法和链地址法。
摘要由CSDN通过智能技术生成

查找

概述

  • 查找 :在具有相同类型的记录构成的集合中找出满足给定条件的记录。

  • 查找的结果 :若在查找集合中找到了与给定值相匹配的记录,则称查找成功;否则,称查找失败。

  • 关键码:可以标识一个记录的某个数据项。

  • 键值:关键码的值。

  • 主关键码:可以唯一地标识一个记录的关键码。

  • 次关键码:不能唯一地标识一个记录的关键码。

  • 静态查找:不涉及插入和删除操作的查找 。(在查找过程中不进行插入删除等操作)

  • 动态查找:涉及插入和删除操作的查找。 (涉及插入和删除操作)

  • 查找结构 :面向查找操作的数据结构 ,即查找基于的数据结构。

  • 线性表:适用于静态查找,主要采用顺序查找技术、折半查找技术。

  • 树表:适用于动态查找,主要采用二叉排序树的查找技术。

  • 散列表:静态查找和动态查找均适用,主要采用散列技术。

  • 平均查找长度:将查找算法进行的关键码的比较次数的数学期望值定义为平均查找长度。或者说是自1到n求和 查找第 i 个记录的概率*查找第 i 个记录所需的关键码的比较次数

线性表查找

顺序查找

int SeqSearch1(int r[ ], int n, int k){
   	// 数组r[1] ~ r[n]存放查找集合   
     int i=n;
     while (i>0 && r[i]!=k)
         i--;
     return i;
}

改进后的顺序查找

int SeqSearch2(int r[ ], int n, int k) {
   	//数组r[1] ~ r[n]存放查找集合   
    r[0]=k;		// 即让0号元素一定会被查到,从而避免了判断是否越界 
    i=n;
    while (r[i]!=k)
        i --;
    return i;
}

在计算ASL的时候,有个奇葩的规定(之后待考证),就是假设成功失败的可能都是1/2

优点
  • 使用面广,算法简单
  • 对存储没有任何要求,顺序和链式均可
  • 对记录有序性也无要求,无论记录是否按照关键码有序
缺点
  • 平均查找长度大,查找效率低

折半查找

条件
  • 线性表中的记录必须按关键码有序
  • 必须采用顺序存储
基本思想

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

实现
// 非递归实现
int BinSearch1(int r[ ], int n, int k){
   	//数组r[1] ~ r[n]存放查找集合 
    low=1;
    high=n;
    while (low<=high) {
   		// 此处一定要记住终止条件
        mid=(low+high)/2;            
        if (k<r[mid])  high=mid-1;
        else if (k>r[mid])  low=mid+1; 
        else return mid;
    }
    return 0;	// 其实是失败了
}

// 递归实现
int BinSearch2(int r[ ], int low, int high, int k){
   	//数组r[1] ~ r[n]存放查找集合    
    if (low>high) return 0;  // 终止条件
    else {
   
        mid=(low+high)/2;
        if (k<r[mid])	// 其实就是将前文的赋值改成了递归 
            return BinSearch2(r, low, mid-1, k);
        else  if (k>r[mid]) 
            return BinSearch2(r, mid+1, high, k); 
        else return mid;
     }
 }
折半查找判定树
定义

折半查找的过程可以用二叉树来描述,树中的每个结点对应有序表中的一个记录,结点的值为该记录在表中的位置。通常称这个描述折半查找过程的二叉树为折半查找判定树,简称判定树。

构造
  • 当n=0时,折半查找判定树为空;

  • 当n>0时,折半查找判定树的根结点是有序表中序号为mid=(n+1)/2的记录,根结点的左子树是与有序表r[1] ~ r[mid-1]相对应的折半查找判定树,根结点的右子树是与r[mid+1] ~ r[n]相对应的折半查找判定树。

性能分析
  • 具有n个结点的折半查找判定树的深度为 [log2n]+1 ([]表示向下取整)(n个节点的判定树和n个节点的完全二叉树深度相同)
  • 查找成功:在表中查找任一记录的过程,即是折半查找判定树中从根结点到该记录结点的路径,和给定值的比较次数等于该记录结点在树中的层数。
  • 查找不成功:查找失败的过程就是走了一条从根结点到外部结点的路径,和给定值进行的关键码的比较次数等于该路径上内部结点的个数,即使是失败了,其关键字比较个数最多也不会超过 [log2n]+1 ([]表示向下取整)

A S L = n + 1 n l o g 2 ( n + 1 ) − 1 ASL = \frac{n+1}{n}log_2(n+1)-1 ASL=n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值