Java二叉树(1)

本文详细介绍了二叉树的基础概念,包括节点度、树的定义、叶子节点、双亲和孩子节点、根节点、层次及高度。还重点探讨了满二叉树和完全二叉树的特点,以及二叉树的遍历方法(先序、中序、后序)及其在链式存储中的应用。
摘要由CSDN通过智能技术生成

🐵本篇文章将对二叉树的相关概念、性质和遍历等知识进行讲解


  一、什么是树

在讲二叉树之前,先了解一下什么是树:树是一种非线性结构,其由许多节点和子节点组成,整体形状如一颗倒挂的树,比如下图:

A就是这棵树的根,BDEF、D、CG、G等都可以看作这颗树的一颗子树,在树形结构中子树之间不能由交集,否则不能称为树,如下图就不是树:

二、树的相关概念

1. 结点的度:一个结点含有子结点的个数称为该结点的度,如A的度为2,B的度3,D的度为0

2. 树的度:所有结点度的最大值称为树的度,比如上树中B的度最大,则该树的度为3

3. 叶子结点/终端结点:度为0的结点称为叶子结点,如上树中的D E F G

4. 双亲结点/父结点:一个结点的前驱结点称为该结点的父结点,如B的父结点为A

5. 孩子结点/子结点:一个结点的后继结点称为该结点的子结点,如B的子结点有D E F

6. 根结点:没有双亲结点的结点称为根结点,上树的根结点为A

7. 结点的层次:从根结点那一层开始定义,A为第一层(有时是从0开始),B C所处第二层,依此类推

8. 树的高度:树中结点的最大层次为称为该树的高度,上树的高度为3

三、二叉树

二叉树是一种特殊的树,一棵所有结点的度都小于等于2的树称为二叉树

二叉树特别讲究顺序,如上图中如果G为C的左孩子,则又是一颗完全不同的二叉树

3.1 满二叉树

从根结点开始,从上到下从左到右每一层都放满了结点的树称为满二叉树,如下图:

若一个满二叉树有k层,则其每一层有2^(k - 1)个结点,整个树共有(2^k) - 1个结点

3.2 完全二叉树

从根结点开始,从上到下从左到右依次存放结点,最后一层可以不满,这样的二叉树称为完全二叉树,如下图:

下图不是完全二叉树:

3.3 二叉树的性质

1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(i - 1)个结点

2. 若规定根结点的层数为1,则一棵非空二叉树的最大结点数是(2^i) - 1

3. 对任何一棵二叉树,如果其叶结点个数为n0,度为2的结点个数为n2,则有n0=n2+1

4. 具有n个结点的完全二叉树高度为:log₂(n + 1)向上取整,如:3.x为4;或者log₂(n) + 1向下取整,如3.x为3

5. 具有n个结点的完全二叉树,从上到下从左到右依次编号,规定根结点的编号为0,则编号为i的结点:双亲编号:(i - 1) / 2;左孩子编号:2i + 1,若2i + 1 > n则无左孩子;右孩子编号:2i + 2,若2i + 2 > n则无右孩子

下面讲一道例题:

一个具有767个节点的完全二叉树,其叶子节点个数为()
A 383
B 384
C 385
D 386

【解析】由于二叉树中的结点的度都不大于2,所以设度为0,1,2的结点的个数分别为n0,n1,n2,则n0 + n1 + n2 = 767,由性质3:n0 = n2 + 1得2*n0 + n1 = 768,在完全二叉树中,度为1的结点只可能有1个或0个,如果n1 = 1,则n0不是一个整数,所以n1只可能为0,经计算n0 = 384

3.4 二叉树的存储

二叉树有两种存储方式,分别为链式存储和顺序存储,这里主要讲解链式存储,接下来用代码以穷举的方式先构造下面这个二叉树

public class BinaryTree {
    static class TreeNode{
        public char val; 
        public TreeNode left; //指向该结点的左孩子
        public TreeNode right; //指向该结点的右孩子

        public TreeNode(char val) {
            this.val = val;
        }
    }
}

接下来以穷举的方式构造二叉树

    public TreeNode creatTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');

        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        E.right = H;
        C.left = F;
        C.right = G;

        return A; //返回这个树的根结点
    }

3.5 二叉树的遍历

二叉树共有3种遍历方式,分别为:先序遍历、中序遍历、后序遍历,接下来会逐个讲解 

3.5.1 先序遍历

先序遍历一个树,按照根、左子树、右子树的顺序遍历这个树,直接看例子:

先遍历这个树的根A,之后遍历A的左B,由于B又是一个子树的根,所以要继续遍历B的左,B的左为空,那就遍历B的右:F,F是一个子树的根,所以要继续遍历F的左:D,D的左右都为空,那么F的左子树全部遍历完毕,接着遍历F的右,F的右为空,那么B的右全部遍历完毕,那接着就是A的左全部遍历完毕,之后遍历A的右:C,C又是一个子树的根,所以要继续遍历C的左,C的左为空,那就遍历C的右:G,G的左右都为空,至此A的右也全部遍历完毕,那么整个二叉树遍历完毕整个遍历的序列为:A B F D C G

3.5.2 中序遍历

先序遍历一个树,按照左子树、根、右子树的顺序遍历这个树,直接看例子:

先遍历A的左,由于A的左也是一个子树,所以要遍历这个子树的左:空,这个子树的左遍历完就要遍历这个树的根:B,之后遍历这个子树的右:F D,这也是一个子树,所以要先遍历这个子树左:D,然后遍历根:F,最后是右,右为空,那么整个二叉树的左遍历完毕,接着遍历根:A,然后遍历右子树:C G,先遍历这个树的左,左为空,然后遍历根:C,最后是右:G,至此整个二叉树遍历完毕,整个遍历的序列为:B D F A C G

3.5.3 后序遍历

先序遍历一个树,按照左子树、右子树、根的顺序遍历这个树,直接看例子:

先遍历这个二叉树的左子树:B F D,这也是一个树,所以先遍历这个树的左,左为空,然后遍历这个树的右子树:F D,这也是一个树,所以要先遍历这个树的左:D,然后遍历这个树的右,右为空,最后是根:F,那么B F D这个子树的右遍历完毕,然后遍历B F D这个树的根:B,至此整个树的左子树遍历完毕,然后遍历这个树的右子树:C G,先遍历这个树的左,左为空,然后遍历右:G,再遍历根C,最后遍历整个树的根:A,整个树遍历完毕,整个遍历的序列为:D F B G C A

3.6 代码实现二叉树的遍历

二叉树的三种遍历需要用递归的思想实现

先序遍历:

    public void preOrder(TreeNode root) {
        if (root == null) { //如果根为空则直接返回
            return;
        }

        System.out.print(root.val +" ");
        preOrder(root.left); //以根的左孩子为新的根继续遍历
        preOrder(root.right); //以根的右孩子为新的根继续遍历
    }

root为null后返回至上一个方法,遍历D的右孩子,右孩子也为空,则以D为根的方法结束返回至上一个方法,遍历B的右孩子

右子树也是同样的道理

中序遍历:

    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }

        preOrder(root.left);
        System.out.print(root.val +" ");
        preOrder(root.right);
    }

后序遍历:

    public void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }

        preOrder(root.left);
        preOrder(root.right);
        System.out.print(root.val +" ");
    }
  • 56
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值