2 - 二叉树

1 树的分类

1.1 二叉树(✓)

在这里插入图片描述

- 深度优先遍历 DFS

  • 树中一个节点的孩子节点的个数叫该节点的度,如A节点2度。

二叉树代码(✓)

在这里插入图片描述

  • 一棵树必有一个根节点
  • 二叉树:有且只有左右孩子

静态创建二叉树(✓)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 遍历重点:递归
  • 出口:节点为空,以上面树为例(前序遍历为例),此时递归到15节点,15不为空,进入if判断,查找他的孩子节点,进入递归,此时它没有孩子节点,所以getLeftChild返回值为null,传入preShowTreeNode(rootNode.getLeftChild()),preShowTreeNode(TreeNode rootNode)此时rootNode为null,if判断失败,退出递归。
package MyTree;

public class TreeNode {

    private TreeNode leftChild;
    private TreeNode rightChild;
    private int value;

    // 构造函数
    public TreeNode(int value){
        this.value = value;
    }
    public int getValue(){
        return this.value;
    }


    // setter 和 getter
    public void setLeftChild(TreeNode tmp){
        leftChild = tmp;
    }
    public void setRightChild(TreeNode tmp){
        rightChild = tmp;
    }
    public TreeNode getLeftChild() {
        return leftChild;
    }
    public TreeNode getRightChild() {
        return rightChild;
    }



    // 前序遍历
    public static void preShowTreeNode(TreeNode rootNode){

        if (rootNode != null){
            // 访问跟节点
            System.out.println("先序---"+rootNode.getValue());

            // 访问左孩子
            preShowTreeNode(rootNode.getLeftChild());

            // 访问右孩子
            preShowTreeNode(rootNode.getRightChild());
        }
    }

    // 中序遍历
    public static void midShowTreeNode(TreeNode rootNode){

        if (rootNode != null){

            // 访问左孩子
            midShowTreeNode(rootNode.getLeftChild());

            // 访问跟节点
            System.out.println("中序---"+rootNode.getValue());

            // 访问右孩子
            midShowTreeNode(rootNode.getRightChild());
        }
    }

    // 后序遍历
    public static void afterShowTreeNode(TreeNode rootNode){

        if (rootNode != null){

            // 访问左孩子
            afterShowTreeNode(rootNode.getLeftChild());

            // 访问右孩子
            afterShowTreeNode(rootNode.getRightChild());

            // 访问跟节点
            System.out.println("后序---"+rootNode.getValue());
        }
    }

}

package MyTree;

public class TreeDemo01 {
    public static void main(String[] args) {
        TreeNode t1 = new TreeNode(10);
        TreeNode t2 = new TreeNode(9);
        TreeNode t3 = new TreeNode(20);
        TreeNode t4 = new TreeNode(15);
        TreeNode t5 = new TreeNode(35);

        t1.setLeftChild(t2);
        t1.setRightChild(t3);
        t3.setLeftChild(t4);
        t3.setRightChild(t5);

        TreeNode.preShowTreeNode(t1);
        TreeNode.midShowTreeNode(t1);
        TreeNode.afterShowTreeNode(t1);


    }
}

在这里插入图片描述

动态创建二叉树(✓)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


1.1.1 满二叉树(✓)

  • 如果一棵二叉树的结点要么是叶子结点要么它有两个子结点,这样的树就是满二叉树。
  • 高度为h,由2^h-1个节点构成的二叉树称为满二叉树。
    在这里插入图片描述

1.1.2 完全二叉树(✓)

  • 一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。(百度百科

  • 完全二叉树是由满二叉树而引出来的,若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数(即1~h-1层为一个满二叉树,h层只有叶子节点)第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

  • 堆一般都是用完全二叉树来实现的。

在这里插入图片描述

1.1.3 完满二叉树(✓)

  • 所有非叶子结点的度都是2。(只要你有孩子,你就必然是有两个孩子
    在这里插入图片描述

1.2 二叉查找树(Binary Search Tree,BST,二叉搜索树,二叉排序树)(✓)

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树
(4)没有键值相等的结点。

在这里插入图片描述

1.3 平衡二叉树(Balanced Binary Tree)(✓)

  • 任意节点的子树的高度差都小于等于1

在这里插入图片描述

1.3.1 为什么要有平衡二叉树(✓)

  • 参考

  • 二叉搜索树一定程度上可以提高搜索效率,但是当原序列有序时,例如序列 A = {1,2,3,4,5,6},构造二叉搜索树如图。依据此序列构造的二叉搜索树为右斜树,同时二叉树退化成单链表,搜索效率降低为 O(n)。
    在这里插入图片描述

  • 在此二叉搜索树中查找元素 6 需要查找 6 次。

  • 二叉搜索树的查找效率取决于树的高度,因此保持树的高度最小,即可保证树的查找效率。同样的序列 A,将其改为图 1.2 的方式存储,查找元素 6 时只需比较 3 次,查找效率提升一倍。
    在这里插入图片描述

  • 可以看出当节点数目一定,保持树的左右两端保持平衡,树的查找效率最高。

  • 这种左右子树的高度相差不超过 1 的树为平衡二叉树。

1.3.2 AVL树(自平衡二叉查找树)(✓)

  • 参考

  • AVL树本质上还是一棵二叉搜索树,它的特点是:

    • 本身首先是一棵二叉搜索树。
    • 带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1
    • 也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

1.3.3 红黑树(✓)

  • 参考
  • 红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。
  • 红黑树使用红黑二色进行“着色”,目的是利用颜色值作为二叉树的平衡对称性的检查,只要插入的节点“着色”满足红黑二色的规定,最短路径与最长路径不会相差的太远,红黑树的节点分布就能大体上达至均衡。

1.4 B树(✓)

  • 参考

  • B 树相当于是一棵多叉查找树

  • 子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);

  • B树比BST在磁盘操作的次数上更少(空间局部性)

  • 适用于文件系统
    在这里插入图片描述

  • 图中是一棵m = 3 的 3 阶 B 树,可以看出,树中有些节点是有多个元素的,并且和二叉查找树一样,左节点的所有元素的值都比父亲元素小。例如对于(3, 7)这个节点。两个元素把这个节点分割成三个值域,即可以有 3 个孩子。2 相当于 3 的左孩子节点,而 (4,6)相当于 3 的右孩子,同时也是 7 的左孩子,而 9 是 7 的右孩子。

  • 和二叉查找树还是很相似滴,都是有序,且左孩子小,右孩子大,只是 B 树的一个节点可以有多个元素,并且有多个分支。而这些分支以及元素的数量规则,可以从上面的五个规则中查找哈。说实话,我也懒的记那些规则,只知道个大概以及 B 树的应用即可。

1.4.1 B+树(✓)

  • 参考
  • B+树是升级版B树,数据都在叶子节点,叶子节点之间加了指针形成链表。
  • 适用于数据库索引,查询时候可能查询很多条,这样就不用跨层访问(链表)
  • hash比B+快,为啥数据库不用hash?
    • 这和业务场景有关。如果只选一个数据,那确实是hash更快。但是数据库中经常会选择多条,这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了。
    • 而且数据库中的索引一般是在磁盘上,数据量大的情况可能无法一次装入内存,B+树的设计可以允许数据分批加载,同时树的高度较低,提高查找效率。

1.4.2 B*树(暂留)

1.5 线索二叉树(暂留)

1.6 最优二叉树(霍夫曼树,哈夫曼树)(✓)

  • 带权路径长度WPL最小的二叉树,权值较大的结点离根较近
  • 把查询比率越大的放在上层,这样查询的时候就不用一直向下查询,时间短。

1.7 字典树(暂留)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值