7. 查找

7.1 线性表的查找

7.1.1 顺序查找
  1. 概念:从表中最后一个记录开始,逐个进行关键字和给定值的比较,若某个记录的关键字和给定值比较相等,则查找成功,否则不成功。

  2. 优化:

    • 使表有序,ASL(成功)更小

    • 按查找概率排序,ASL(成功)更小

  3. 查找判定树,n+1种失败的可能

7.1.2 折半查找
  1. 概念:先确定待查记录的范围,然后缩小范围,直至找到或找不到该记录。设两个指针low、high,分别指示待查元素所在范围的上界和下界,mid指向中间位置,每次和a[mid]比较,比a[mid]大,low = mid + 1,比a[mid]小,high = mid -1,如果low > high,查找失败。

  2. 查找判定树:

  • 一定是平衡二叉树,满足二叉排序树(关键字,左<中<右)
  • 只有最下面那层不是满的
  • 不考虑失败结点,h = log(2)(n + 1)
7.1.3 索引查找
  1. 概念:索引查找是顺序查找的改进发放,除了表本身以外,还需要建一个索引表,索引表一般是块内关键字最大的记录。索引表按关键字有序,表分块有序(块内无序,块间有序),即第一块子表比第二块子表都小,第三块比第二块都大,以此类推。。。
  2. 查找顺序:先确定待查记录所在的块,由于块间是有序的,这个过程可以用二分查找,再在块中查找。
7.1.3 查找算法的比较
查找算法的比较 顺序查找 折半查找 分块查找
ASL 最大 最小 中间
表结构 有序表、无序表 有序表 分块有序
存储结构 顺序表、线性链表 顺序表 顺序表、线性链表

7.2 树的查找

7.2.1 二叉排序树
  1. 概念:二叉排序树要么是一颗空树,要么是满足以下条件的树:

    ①若他的左子树不空,则左子树所有结点的值都小于它的根节点的值

    ②若它的右子树不空,则右子树所有结点的值都大于它的根节点的值

    ③它的左、右子树也分别为二叉排序树

  2. 二叉排序树的构造方法

    从一棵空树出发,依次输入元素,将它们插在二叉树中的合适位置

。插入的过程如下:若二叉树为空,直接插入结点,否则:若插入的元素关键字小于根节点,插入到左子树,大于根节点,插入到右子树。插入的结点一定是新添加的叶子结点,无需挪动其他记录。

  1. 二叉排序树的删除,分三种情况

    ①若删除的结点是叶子结点,则直接删除

    ②若被删除的结点,只有一棵子树,那么让子树代替这个父节点的位置。

    ③若被删的结点有左、右两棵子树,那么就得找被删结点的直接后继或者直接前驱来代替被删的结点,就会变成以上两种情况。

  2. 二叉排序树的查找效率分析

    • 主要取决于树的高度,如果二叉排序树是平衡二叉树,它的平均查找长度是O(log(2)n),如果是单支树(类似于有序的单链表),它的平均查找长度为O(n)。

    • 就性能而言,类似于二分查找,但是二分查找判定树唯一,二叉排序树不唯一,相同的关键字因为插入顺序不同会形成不同的二叉排序树。

7.2.2 平衡二叉树
  1. 概念:为了避免二叉排序树的高度增长过快,降低二叉排序树的性能,规定在插入或者删除二叉树的节点时,要保证左右子树的高度的绝对值不超过1,这想的二叉树就是平和二叉树。定义结点左子树于右子树的高度差为该节点的平衡因子,那么平衡二叉排序树的结点的平和因子只可能是-1、0、1。

  2. 插入:每次调整的对象都是最小不平衡子树。分以下四种情况:

    ①LL平衡旋转:在结点A的左孩子的左子树上插入新节点导致不平衡,需要向右旋转。A的左孩子代替A,A向右旋转成为右孩子。

    ②RR平衡旋转:在结点A的左孩子的左子树上插入新节点导致不平衡,需要向左旋转。A的右孩子代替A,A向左旋转成为左孩子。

    ③LR平衡旋转:在A的左孩子的右子树上插入新节点,以A为根的子树失去平衡。需要先左旋,再右旋,设祖孙三代为ABC,先把C调到B的位置,再C调到A的位置。

    ④RL平衡旋转:在A的右孩子的左子树上插入新节点,以A为根的子树失去平衡。需要先右旋,再左旋,设祖孙三代为ABC,先把C调到B的位置,再C调到A的位置。

  3. 求深度为h的平衡二叉树含有的最小结点数nh:n0 = 0, n1 = 1, n2 = 2,nh = n(h-1) + n(h- 2) + 1。

7.3 散列表

7.1 概念

​ 查找的效率依赖于查找过程中的比较次数,理想的情况希望不经过任何比较,一次存取就能得到所查的记录,那么就必须再记录的存储位置和它的关键字之间建立一个对应关系f,我们称这个对应关系f为哈希函数,按这个思想建的表为哈希表。

7.2 冲突

不同的关键字可能得到统一哈希地址,这种现象称冲突,具有相同函数值的关键字称为同义词。解决冲突的办法:

  1. 开放定址法:Hi = (H(key) + di) % m

    ①线性探测法:di = 0,1,2,...

    ②平方探测法:di = 02,12,-12,22,-2^2

    ③再散列法:Hi = (H(key) + i * H2(key)) % m

    ④di为伪随机序列

  2. 拉链法:将所有的同义词存储再一个线性链表中。

7.3 哈希函数的构造方法
  1. 直接定址法:

①概念:取关键字或关键字的某个线性函数值作为哈希地址。即:

​ H(key) = key 或 H(key) = a * key +b

​ 不会产生冲突,但浪费空间

  1. 除留余数法:

    ①概念:这是一种最简单、最常用的办法,假定表长为m,与一个不大于m但是接*或等于m的质数p,散列函数为H(key) = key % p

    关键是选好p

  2. 数字分析法:
    ①概念:设关键字是r进制数,r个数码在各位上出现的频率不一定相同,可能在某些位上分别比较均*,**随机的。那么可以任取其中两位,或者与另外两位的叠加求和作为哈希地址。

    缺点:这种方法适合已知的关键字集合,更换了关键字,需要更换哈希地址。

    eg:手机号

  3. 平方取中法:

    ①概念:取关键字的平方值的中间几位作为散列地址。

7.4 查找不成功的平均查找长度
posted @ 2021-12-09 14:54  某科学的撒把豆子  阅读(81)  评论(0)    收藏  举报