查找(折半查找、分块查询、二叉排序树、AVL树、B-树和B+树、键树)

        计算机科学中的定义:在一些(有序的/无序的)数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程叫做查找。(根据给定的某个值,在查找表中确定一个关键字等于给定值的记录或数据元素。)

静态查找表

1.顺序表的查找(略)

2.有序表的查找(折半查找)

    public static int binarySearch(int[] nums, int low, int high, int target) {
        while (low <= high) {
            int middle = (low + high) / 2;
            if (target == nums[middle]) {
                return middle;
            } else if (target > nums[middle]) {
                low = middle + 1;
            } else if (target < nums[middle]) {
                high = middle - 1;
            }
        }
        return -1;
    }

3.静态树表的查找

当有序表中各记录的查找概率不等时,对于使用折半查找算法,按照之前的方式进行,其查找的效率并不一定是最优的。可以根据之前介绍的折半查找算法,建立相应的判定树(树中各关键字用概率表示),称该二叉树为静态最优查找树

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

以索引顺序表表示静态查找表,则在搜索过程中可用分块查找来实现。

分块查找又称索引顺序查找

动态查找表

动态查找表的特点是表结构本身是是在查找过程中动态生成的,

即对于给定值key,若表中存在其关键字等于key的记录,则查找成功返回,否则插入关键字等于key的记录。

1.二叉排序树(Binary Sort Tree

  • 空树
  • 或者是具有下列性质的二叉树:

        (1)若左子树不空,则左子树上所有结点的值均小于它的结点的值;

        (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

        (3)左、右子树也分别为二叉排序树;

        (4)没有键值相等的结点。(也可以不做要求)

可使用递归进行增删改查结点(略)。

缺点:当表中数据呈顺序结构时,构建的二叉排序树会退化成链表。

2.平衡二叉树(Balanced Binary Tree or Height-Balanced Tree

平衡二叉树又称AVL树:

  • 空树
  • 或者是具有下列性质的二叉树:

(1)它的左子树和右子树都是平衡二叉树;

(2)且左子树和右子树的深度之差的绝对值不超过1。

二叉树上结点的平衡因子BT(Balance Factor)定义为该结点的左子树的深度-它的右子树的深度(平衡因子取值:-1,0,1

  • 平衡二叉树不会出现退化成链表的情况,但需要维护这种平衡,如何维护平衡?

添加结点:

前提:每个结点的高度可知,每个结点的平衡因子可知

方式:通过AVL旋转

情况:

设平衡因子BT的计算是左子树深度-右子树深度,a是离插入点最近,且平衡因子绝对值超过1的祖先结点

LL旋转(单向右旋):(在a的左子树根结点的左子树上插入结点

结点a的左子树根结点BT=2,结点a的左子树根结点的左子树结点BT=1,则

tmp(临时变量)=a.left.right;

a.left.right=a;

a.left=tmp;

RR旋转(单向左旋):(在a的右子树根结点的右子树上插入结点

结点a的右子树根结点BT=-2,结点a的右子树根结点的右子树结点BT=-1,则 

tmp(临时变量)=a.right.left;

a.right.left=a;

a.right=tmp;

LR旋转(双向旋转,先左后右):(在a的左子树根结点的右子树上插入结点

结点a的左子树根结点BT=2,结点a的左子树根结点的左子树结点BT=-1

RL旋转(双向旋转,先右后左):(在a的右子树根结点的左子树上插入结点

结点a的右子树根结点BT=2,结点a的右子树根结点的右子树结点BT=1

(旋转后要维护结点的高度)

删除结点:

1.被删除结点是叶子结点,直接删除,并回溯,更新所有祖先结点的高度并检查BT,维护平衡;

2.被删除结点有null子结点,使用非null的子结点替换其原来位置即可,然后维护高度和检测BT,维护平衡;

3.被删除结点左右孩子都非空,有两种解决办法:

(1)找左子树中最大的结点替换其位置;

(2)找右子树中最小的结点替换其位置。

(前提,该AVL树是左小右大(左孩子始终小于右孩子)的二叉搜索树)

总结:

个人感觉维护BT是一件棘手的事,这才有了2-3树,红黑树。

实现会单独写一篇!!!

 3.B-树和B+树

 B-树

(1)一种平衡的多路查找树。(多用于文件系统中)

(2)一棵m阶的B-树:或为空树;或为满足下列特性的m叉树:

  • 根结点至少有两棵子树;
  • 除根之外所有非终端结点至少有⌈m/2⌉可棵子树;
  • 所有的叶子结点都位于同一层;
  • 所有的非终端结点中包含信息数据(n,A0,K1,A1,K2,A2,...,Kn,An)。

[n表示包含的关键字数量且(⌈m/2⌉ - 1 <= n <= m - 1)K为关键字Ki<K(i+1),A表示指向子树根结点的指针,实际上在B-树的每个结点中还应包含n个指向每个关键字的记录的指针,An所指子树中所有结点的关键字均大于Kn]

  B+树

一种B-树的变型树。

一棵m阶的B+树和m阶的B-树的差异在于:

(1)有n棵子树的结点中含有n个关键字。

(2)所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。

(3)所有的非终端结点可以看成是索引部分,结点中仅含有其子树(根结点)中的最大(或最小)关键字。

4.键树

键树又称数字查找树(Digital Search Trees)

本人写的Trie就是键树的一种,有空可以了解一下。

5.更多

2-3树,红黑树,线段树,B*树等等,有空再聊~

猜你喜欢

转载自blog.csdn.net/qq_40100414/article/details/118672536