一次性明白常见树形结构和不同

274 阅读5分钟

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

推荐一个数据结构学习网站: www.cs.usfca.edu/~galles/vis…

一、二叉搜索树

1.1 性质:

1.若任意结点的左子树不空,则左子树上所有结点的值均不大于它的根结点的值。
2. 若任意结点的右子树不空,则右子树上所有结点的值均不小于它的根结点的值。
3.任意结点的左、右子树也分别为二叉搜索树。

image.png

1.2 java实现一个二叉搜索树:

package com.cloud.bssp.indexing;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomUtils;

/**
 * 二叉搜索树
 * @date: 2020/10/27
 * @author weirx
 * @version 3.0
 */
public class BinarySearchTree {

    private static class Node {
        int data;
        Node left;
        Node right;
    }

    /**
     * 根节点
     */
    private static Node root;

    public static void insert(int data) {
        //最终树
        Node result;
        //得到一个节点
        Node node = new Node();
        node.data = data;
        //判断当前根节点是否为空
        if (ObjectUtils.isEmpty(root)) {
            //空?
            root = node;
        } else {
            //非空?
            //初始化一个当前节点,用于后面循环增加节点
            Node current = root;
            while (true) {
                result = current;
                if (data >= current.data) {
                    //添加到右侧
                    current = current.right;
                    if (ObjectUtils.isEmpty(current)) {
                        result.right = node;
                        return;
                    }
                } else {
                    //添加到左侧
                    current = current.left;
                    if (ObjectUtils.isEmpty(current)) {
                        result.left = node;
                        return;
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        int num;
        for (int i = 0; i < 10; i++) {
            num = RandomUtils.nextInt(0, 10);
            BinarySearchTree.insert(num);
            System.out.println(num);
        }
        //没实际意义,用于打个断点观察root
        System.out.println();
    }
}

二、AVL树

AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

2.1 特点:

AVL树本质上还是一棵二叉搜索树:

1.本身首先是一棵二叉搜索树。
2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

2.2 四种旋转方式:

从最下级节点起,开始旋转。

1、左单旋

image.png

2、右单旋

左单旋相反

3、先右旋再左旋

image.png

4、先左旋再右旋

参看上一个图

三、红黑树

3.1 为什么出现红黑树?

AVL树是严格的平衡二叉树,平衡条件必须满足(所有节点的左右子树高度差的绝对值不超过1)。不管我们是执行插入还是删除操作,只要不满足上面的条件,就要通过旋转来保持平衡,而旋转是非常耗时的,由此我们可以知道AVL树适合用于插入与删除次数比较少,但查找多的情况

鉴于上述的局限性,更多的地方是用追求局部而不是非常严格整体平衡的红黑树

3.2 什么是红黑树?

红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。 红黑树是一种特化的AVL树,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。

3.3 红黑树的特征

性质1. 节点是红色或黑色。

性质2. 根节点是黑色。

性质3.所有叶子都是黑色。(叶子是NULL节点,如下图中的NULL LEAF)

性质4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

因为红黑树是一种特化的二叉查找树,所以红黑树上的只读操做与普通二叉查找树相同。

image.png

在满足上述的性质下,红黑树会进行旋转,通常都是进行局部旋转,前提是能满足以上的性质,如果实在无法满足,则会对根节点进行旋转,此时是一个全局的旋转。 ####应用场景 java8中的TreeMap和HashMap。

四、B 树

4.1 什么是B树?

B树,全名是平衡多路查找树,是对二叉查找树的改进,它的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,减少硬盘操作次数,B树大量应用在数据库和文件系统当中。

4.2 为什么出现B树?而不是红黑树?

1、红黑树是二叉树,二B树是多叉的。

2、根据计算机的局部性原理,B树将很多相近甚至连续的值存放在一个节点上,这样在获取数据时,B树可以一次获取更多的相关信息,二红黑树一次只能获取一个数据信息。

3、B树因为是多路的,相同数据量,就证明其高度要明显低于红黑树,在效率上也明显高于红黑树。

4.3 B Tree的结构

对于一棵m阶B tree:

1、每个结点至多可以拥有m个子结点。

2、根结点至少有2个子结点,除非根结点为叶子节点,根结点中关键字的个数为1~m-1。

3、非根结点至少有[m/2]([],向上取整)个子结点,相应的,关键字个数为[m/2]-1~m-1

4.4 B树节点信息

1、本结点所含关键字的个数;

2、指向父结点的指针;

3、关键字;

4、指向子结点的指针;

image.png

五、B+ 树

B+树是B树的一个升级版,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找。

5.1 B+树与B树的不同

1、在B+树种,非叶子节点值存数据的key和子节点指针信息,不存储数据的具体值data的指针,这使得B+树可以存储更多的key。B+树的所有数据data存储在叶子节点上。

2、在叶子节点上,每个叶子结点增加顺序指针,形成链表结构,便于区间查找和遍历,非叶子结点作为索引。(非叶子节点也有横向指针的叫做B*树)

B树如下所示:
B树

B+树如下所示:
B+树