《数据结构》第七章 查找

第七章 查找

7.1 查找的基本概念

查找表:是由同一类型的数据元素(或记录)构成的集合;
关键字:是数据元素(或记录)中某个数据项的值,用它可以表示一个数据元素(或记录);
主关键字:可以唯一地标识一个记录;此关键字:以识别若干记录的关键字;
查找:根据给定的某个值,在查找表中确定一个其关键字等于给定值的记录或数据元素;
动态查找表:在查找的同时能对表内数据进行操作的表;
静态查找表:只能查找不能操作的表;
平均查找长度:关键子个数的期望值(平均比较次数)查找算法时查找成功的平均查找长度,用ASL表示;

7.2 线性表的查找

7.2.1 顺序查找

顺序查找的过程:从表头的一端开始根据给定的值和表内的值进行比较,若相等则查找成功,反之则查找失败;
设置监视哨的顺序查找:在开始查找的表头的另一端设置监视哨,将需要查找的数据放入其中,若查找失败则返回监视哨的位序0;
优点:这个改进能使顺序查找在ST.length>=1000时,进行依次查找所需的平均时间几乎减少一半;

7.2.2 折半查找

折半查找也称二分查找:每次将待查记录所在的区间缩小一半;
算法描述:
用三个指针high,mid,low分别指向表区间的上界 中间位置和下界;
通过比较待查找数据元素的区间来移动指针再进行比较,直到比较完成或成功查找;
优点:效率高,比较次数少;
缺点:对表结构要求高,只能采用顺序表的形式;

7.2.3 分块查找

分块查找又称索引查找:需建立一个“索引表”,分区间,将区间内的最大关键字放入表中并填入起始地址;先确定待查记录所在的块,然后再块中顺序查找;

7.3 树表的查找

7.3.1 二叉排序表

1.二叉排序树的定义
  1. 若它的左子树不空,则左子树上所有结点的值均小于它根结点的值;
  2. 若它的右子树不空,则右子树上所有结点的值均大于它根结点的值;
  3. 它的左右子树也分别为二叉排序树;
    性质:中序遍历二叉树时可以得到一个结点值递增的有序序列;
2.二叉排序树的查找
  • 若二叉树为空,则查找失败,返回空指针;
  • 若查找的关键字小于根结点的关键字,则递归查找左子树;
  • 若查找的关键字大于根结点的关键字,则递归查找右子树;
    平均查找长度:n+1/2;
3.二叉排序树的插入

新插入的结点一定时一个新添加的叶子结点;

  • 若二叉树为空,则插入的元素为树的根结点;
  • 若查找的关键字小于根结点的关键字,则将结点插入左子树;
  • 若查找的关键字大于根结点的关键字,则将结点插入右子树;
4.二叉排序树的创建
  • 将二叉排序树T初始化为空;
  • 读入一个关键字为key的结点;
  • 如果读入的关键字非结束标志,则循环执行以下操作:
  1. 将此结点插入二叉排序树T中;
  2. 读入一个关键字为key的结点;
5.二叉排序树的删除

假定:被删结点为p,双亲结点为f,PL和PR为左右子树;

  1. 若*p结点为叶子节点,直接赋予为空;f->lchild = NULL;
  2. 若*p结点只有左子树或PL只有右子树PR,则直接令PL或PR为 *p的双亲结点的左子树或右子树即可;
    f->lchild = p->lchild(p->rchild);
  3. 若*p结点的左子树和右子树均不空:
  • 用*p的前驱(左子树中最大的元素)或后继(右子树中最小的元素)代替;
  • 令*p的左子树接到其他结点的左子树上,右子树接到其他节点的右子树上;

7.3.2 平衡二叉树

1.平衡二叉树的定义

二叉树上结点的平衡因子定义为该结点左子树和右子树的深度之差,则平衡二叉树上所有结点的平衡因子只能是1,0,-1;
**平衡二叉树(又称AVL树)**的特征:

  1. 左子树和右子树的深度之差的绝对值不超过1;
  2. 左子树和右子树也是平衡二叉树;
2.平衡二叉树的平衡调整方法

找到离插入结点最近且平衡因子绝对值超过1的祖先结点,以该结点为根的子树称为最小不平衡子树;
LL型,LR型,RL型,RR型的调整方法都为将最小不平衡子树中最大的元素移到右子树,其次移到根结点,最小的移到左子树;

7.3.3 B-树

7.3.4 B+树

7.4 散列表的查找

7.4.1 散列表的基本概念

散列查找法(杂凑法或散列法):对元素的关键字值进行某种运算,直接求出元素的地址,即使用关键字到地址的直接转换方法,而不需要反复比较;
优点:查找效率高; 缺点:空间效率低
散列函数和散列地址:在记录的存储位置p和关键字key之间建立一个确定的对应关系H,使p = H(key),称这个对应关系H为散列函数,p为散列地址;
散列表:一个有限连续的地址空间,用以存储按散列函数计算得到相应散列地址的数据元素;
冲突:对不同的关键字可能得到同一散列地址的现象;
同义词:具有相同函数值的关键字;

7.4.2 散列函数的构造方法

  1. 直接定址法:Hash(key)=a.key + b;一次函数
    优点:以关键码key的某个线性函数值为散列地址,不会产生冲突;
    缺点:要占用连续空间,空间效率低;
  2. 数字分析法:若数字较多或较大,则取用后四位数字来进行存储;
  3. 平方取中法:若不知道关键字的分布且位数不是很大,则将数字进行平方取中间的数字进行存储;
  4. 折叠法:若散列地址的位数较少,而关键字的位数较多,且难于直接从关键字中找到取值较分散的几位,将关键字从左到右分割成位数相等的几部分(注意最后一部分位数不够时可以短些),然后将这几部分叠加求和,并按散列表表长,取后几位(舍去进位)作为散列地址。
  5. 除留余数法:H(key) = key % p;所得的余数为散列地址;
    关键:选取适当的数p(不大于表长的数);

7.4.3 处理冲突的方法

1.开放地址法

基本思想:把记录都存储在散列表数组中,当某一记录关键字key的初始散列地址H0=H(key)发生冲突时,以H0为基础,采取适合方法计算得到另一个地址H1,一次得到另一个地址直到将关键字存储进去;

  • 线性探测法
  • 二次探测法
  • 伪随机探测法
2.链地址法

基本思想:把具有相同散列地址的记录放在同一个单链表中,称之为同义词链表;
优点:非同义词不会冲突,无“聚集”现象;
链表上结点空间动态申请,更适合表长不确定的情况;

7.4.4 散列表的查找

给定关键字key,根据创建散列表的散列函数计算H0 =H(key)查找,直到查找成功;
小结:散列表技术具有很好的平均性能,优于一些传统的技术;
链地址法优于开地址法;
除留余数法作散列函数有欲其他类型函数;

7.5 小结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值