C++ 数据结构(十一查找)


基本概念

主键、次键(数据库中也有):唯一确定的是主键如学号;次键不唯一确定如姓名,1号张三2号张三。
查找表:动态能增删改成的表,静态只能查找的表。表中元素类型相同。
查找:找到主键(表中元素)的过程。
平均查找长度ALS( a verage serch length):衡量查找方法,记录平均的查找次数;

静态查找表

静态查找表结构

还记得线性表吗? 基于数组顺序存储、线性表指针索引的链式存储

顺序查找

顺序查找=别称=线性查找。

这里最好有个ASL 的分析

有序表的二分查找
二分法查找的基本思想

二分查找 对分查找 折半查找(总有些不同人,根据不同学术素养对同一个名词有自己的理解)
要求: 查找表是1线性有序2顺序存储
基本思想:

  1. 找到中间点位置:mid = [(low/high)/2]向下取整
  2. 判断配比较:Element[mid].key ?= k;相等则成功,不等继续查找。
  3. 若递增:
    a. Element[mid].key < k ,则Element[low……mid].key <k;重新定义查找区间:Element[mid+1……high].key。(low= mid+1;移动最小值标识,重新定义查找区间)
    b. Element[mid].key > k,则Element[mid……high].key >k;重新定义查找区间:Element[low……mid-1].key。(mid-1 = high;移动最大值标识,重新定义查找区间)
  4. 循环3. 若找到或查找结束则终止
二分判定树

二分查找树 又称二分法的判定树、比较树;
相关概念:

  • 源(圆)节点:树中的内节点,其中的数字表示该节点在有序表中的位置
  • 外节点:源节点中的所有空指针均用一个虚拟的方形节点表示
  • 标记:<查找左子树;>查找右子树;=结束返回;~表示中间值。
    在这里插入图片描述
二分查找优缺点

效率高
对存储表要求高

有序表的斐波那契查找和差值查找
  • 斐波那契查找:斐波那契查找是通过斐波那契序列对有序表进行分割,查找区间的两个端点和中点都与斐波那契数有关。

  • 很关键的一句话:斐波那契搜索也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。
    查找步骤:

    1. 设置初始区间: low = 1、high = F(k) - 1.F = F(k) - 1, off = F(k-1)-1,其中F为表长,off为取得中间点相对偏移量、
    2. low>higt时,返回查找失败信息。
    3. 当low< = high时,令mid = low + off。
      若k<Element[mind].key, 则p=off,off= F-off-1,即计算取中点的相对偏移量;F=p,即调整表长F;high=mid-1,即查找左半区,然后转步骤2.
      若k>Element[mind].key, 则F=F-off-1,即调整表长;off=off-F-1,即计算取中点的相对偏移量;low=mid+1,即查找右半区,然后转步骤2.
      若k=Element[mind].key, 返回数据元素在表中的位置。
      在这里插入图片描述
会有代码的
  • 插值查找:总是在预期地址附近开始查找,这样成为插值查找。(从字典中查找王字,从字母W开始找)
  • 插值查找思想:插值查找,有序表的一种查找方式。插值查找是根据查找关键子与查找表中最大最小记录关键字比较后的查找方法。插值查找基于二分查找,将查找点的选择改进为自适应选择,提高查找效率。插值查找是在折半查找的基础上进行优化,将mid的值 m i d = l o w + h i g h 2 mid = \frac{low + high}{2} mid=2low+high修改 m i d = l o w + h i g h − l o w 2 mid=low+\frac{high-low}{2} mid=low+2highlow在变换为 l o w = l o w + ( h i g h − l o w ) ∗ ( k e y − R [ l o w ] ) R [ h i g h ] − R [ l o w ] low = low+\frac{(high-low)*(key-R[low])}{R[high]-R[low]} low=low+R[high]R[low](highlow)(keyR[low]) 将查找关键字于查找表中的最大最小关键字对比后进行查找。key是查找值,R是有序表。
    插值时满足两个假设
    1. 数据有序,且呈现均匀分布特征
    2. 每次访问与通常指令相比,费用都是相当昂贵的;如,查找表一定是在磁盘非内存中,因此每次访问都进行磁盘访问(不懂前面一句)
分块查找

分块查找又称索引查找,对顺序查找的改进。算法思想简单,见表:
在这里插入图片描述
要求:

将n个数据元素"按块有序"划分为m块(m ≤ n)。 每一块中的结点不必有序,但块与块之间必须"按块有序"; 即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字; 而第2块中任一元素又都必须小于第3块中的任一元素,……

动态查找表

当用线性表作为标的组织结构时,二分法效率最高。但是插入删除操作频繁时,会抵消这一优点。可采用特殊的二叉树作为表的组织形式。(可称为树表)

二叉排序树

二叉排序树=二叉查找树=二叉分类树
特性:

  • 若左子树不空,则左子树所有的节点小于根节点值;若右子树不为空,则右子树所有节点大于根节点值。
  • 左右子树都是二叉排序树。
在这里插入代码片

查找过程:

  1. ?空树
  2. 不,相等吗?等->结束;不等:
    当k小于根节点,查找将在左子树进行->1
    当k大于根节点,查找将在右子树进行->1
在这里插入代码片

插入操作:
先查找,若存在怎不插入;不存在插入
删除:

  • 只有叶子节点,直接链接上一个节点

  • 单个子树,直接链接上一个节点

  • 左右子树,1)左子树,移动到右子树最左;2)右子树最左移到删除位置。

平衡二叉树

平衡二叉树特性:

  • 左子树和右子树都是平衡二叉树
  • 左子树和右子树高度差绝对值不超过1
很难回头写 可惜我是浪子(不回头)

平衡二叉树的插入:
平衡二叉树的删除:

红黑树

每个节点都有颜色特性的二叉排序树,颜色为红色或黑色。属性:

  • 节点红色或黑色
  • 根节点黑色
  • 所有叶子节点是黑色
  • 每个红色节点两个子节点都是黑色
  • 从每个叶节点到根节点所包含的相同数目的黑色节点
    插入:
    删除:
B/B+B-树

B树特性:

  • 树中有M棵子树
  • 若根节点不是叶节点,至少两个子树
  • 除根节点之外的所有非终结点至少[m/2]棵子树
  • 所有的终结点中包含以下信息数据:n,A0、K1、A1、K1…KN、AN。其中Ki(i=(1,n))为建,且Ki<Ki+1,Aj所指子树中所有节点的键均大于Kn【n/2】-1<=n<=m-1,n为键个数。
  • 所有的叶子节点都出现在同一层上,并且不带信息

查找:
删除:
B±…

散列查找

前面查找方法由于数据元素和存储位置与键之间不存在对应关系,因此查找需要进行一系列对键的查找比较,即查找算法是建立在比较的基础上,查找效率由比较一次缩小范围决定。

散列表与散列方法

散列表:散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
散列表的冲突现象:散列表的查找过程基本上和造表过程相同。一些关键码可通过散列函数转换的地址直接找到,另一些关键码在散列函数得到的地址上产生了冲突,需要按处理冲突的方法进行查找。

常用的散列函数
  • 直接定址法
  • 除留余数法
  • 乘余取整法
  • 数字分析法
  • 平方取中法
  • 折叠法
  • 随机数法

你要知道这么多方法 哎……

处理冲突的方法
  • 开放定址法
  • 拉链法(链地址法)
  • 建立一个公共溢出区
散列表的查找分析
  • 查找成功时的平均查找长度
  • 查找不成功的ASL
散列表的操作

不写了累了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Echo一

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

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

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

打赏作者

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

抵扣说明:

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

余额充值