集合-二叉树

1. 什么是二叉树

二叉树是树的一种,二叉树每个节点最多有两个子节点,即结点的度最大为 2。

结点的度:结点拥有的子节点个数。

树的深度:根节点到底层节点的层数。

在这里插入图片描述

二叉树的一些性质:

  • 二叉树第 i 层上的结点数目最多为 2 ^ ( i - 1 ) ( i ≥ 1 )
  • 深度为 h 的二叉树至多有 2 ^ h - 1 个结点 ( h ≥ 1 )
  • 包含 n 个结点的二叉树的高度至少为 log 2 ( n + 1 )
  • 在任意一棵二叉树中,若终端结点的个数为 n0,度为 2 的结点数为 n2,则 n0 = n2 + 1

二叉树的结构举例:

/**
 *@ClassName: BinTree
 *@Description: 二叉树类
 *
 */
public class BinTree {

    /**
     *@ClassName: Node
     *@Description: 内部类,表示二叉树的每一个节点
     *
     */
    private class Node {
        // 每个节点的数据
        private Object data;
        // 左子树指针
        private Node left;
        // 右子树指针
        private Node right;
        }
    }

    // 二叉树的根节点
    private Node rootNode;
}

2. 特殊的二叉树

斜树: 所有节点只有左子树或右子树

在这里插入图片描述

满二叉树: 所有的分支节点都具有左右节点

在这里插入图片描述

完全二叉树: 设二叉树深度为 h,除第 h 层外,其它各层 (1~h - 1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边。

在这里插入图片描述

二叉查找树: 当前根节点的左边全部比根节点小,当前根节点的右边全部比根节点大。

在这里插入图片描述

3. 二叉树的遍历

二叉树有三种遍历方式:先序遍历、中序遍历、后序遍历。

  • 先序遍历:先访问根节点,然后访问左节点,最后访问右节点 ( 根 -> 左 -> 右 )。
  • 中序遍历:先访问左节点,然后访问根节点,最后访问右节点 ( 左 -> 根 -> 右 )。
  • 后序遍历:先访问左节点,然后访问右节点,最后访问根节点 ( 左 -> 右 -> 根 )。

举例:

在这里插入图片描述

先序遍历:1 2 4 8 9 5 10 3 6 7

中序遍历:8 4 9 2 10 5 1 6 3 7

后序遍历:8 9 4 10 5 2 6 7 3 1

使用案例:

package work.java.xzk10301002.bintree;

/**
 *@ClassName: BinTree
 *@Description: 二叉树类
 *
 */
public class BinTree {

    /**
     *@ClassName: Node
     *@Description: 内部类,表示二叉树的每一个节点
     *
     */
    private class Node {
        // 每个节点的数据
        private Object data;
        // 左子树指针
        private Node left;
        // 右子树指针
        private Node right;

        public Node(Object data) {
            this.data = data;
        }
    }

    // 二叉树的根节点
    private Node rootNode;

    public Node getRootNode() {
        return rootNode;
    }

    public BinTree() {
    }

    /**
     * @Description //TODO 根据数组的数据创建一个二叉树
     * @Param [dataArray] 数组
     * @return void
     **/
    public void creatTreeByArray(Object[] dataArray) {
        int end = dataArray.length - 1;
        // 获得根节点并储存
        this.rootNode = getNode(dataArray, 0, end);
    }

    /**
     * @Description //TODO 使用递归的方法创建二叉树
     * @Param [dataArray, start, end] dataArray为节点数据数组,start为数组第一个元素的索引,end为数组最后一个元素的索引
     * @return work.java.xzk10301002.bintree.BinTree.Node 返回二叉树的根节点
     **/
    public Node getNode(Object[] dataArray, int start, int end) {
        Node rootNode;
        // 数组还有数据则二分
        if (start <= end) {
            // 获取数组中间值的索引
            int middle = (start + end + 1) / 2;
            // 以数组中间的数据为根节点创建节点
            rootNode = new Node(dataArray[middle]);
            // 使用递归创建当前根节点的左子树
            rootNode.left = getNode(dataArray, start, middle - 1);
            // 使用递归创建当前根节点的右子树
            rootNode.right = getNode(dataArray, middle + 1, end);
        } else {
            // 二分后不存在数据了表示已经到了叶子节点的,叶子节点都指向null
            rootNode = null;
        }
        // 递归出口,返回当前根节点
        return rootNode;
    }

    /**
     * @Description //TODO 使用递归的方式先序遍历二叉树
     * @Param [rootNode] 二叉树的根节点
     * @return void
     **/
    public void preorderTraversal(Node rootNode) {
        // 递归出口,不存在该节点则返回上一层
        if (rootNode == null) {
            return;
        }
        // 先打印根节点信息
        System.out.print(rootNode.data);
        System.out.print("  ");
        // 打印左子树
        preorderTraversal(rootNode.left);
        // 打印右子树
        preorderTraversal(rootNode.right);
    }

    /**
     * @Description //TODO 使用递归的方式中序遍历二叉树
     * @Param [rootNode] 叉树的根节点
     * @return void
     **/
    public void inorderTraversal(Node rootNode) {
        if (rootNode == null) {
            return;
        }
        inorderTraversal(rootNode.left);
        System.out.print(rootNode.data);
        System.out.print("  ");
        inorderTraversal(rootNode.right);
    }

    /**
     * @Description //TODO 使用递归的方式后序遍历二叉树
     * @Param [rootNode] 叉树的根节点
     * @return void
     **/
    public void postorderTraversal(Node rootNode) {
        if (rootNode == null) {
            return;
        }
        postorderTraversal(rootNode.left);
        postorderTraversal(rootNode.right);
        System.out.print(rootNode.data);
        System.out.print("  ");
    }
}
package work.java.xzk10301002.bintree;

/**
 *@ClassName: BinTreeTest
 *@Description: 二叉树遍历演示的启动类
 *
 */
public class BinTreeTest {
    public static void main(String[] args) {
        Object[] dataArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        BinTree tree = new BinTree();
        tree.creatTreeByArray(dataArray);
        System.out.print("先序遍历二叉树:");
        tree.preorderTraversal(tree.getRootNode());
        System.out.println();
        System.out.print("中序遍历二叉树:");
        tree.inorderTraversal(tree.getRootNode());
        System.out.println();
        System.out.print("后序遍历二叉树:");
        tree.postorderTraversal(tree.getRootNode());
    }
}

运行结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值