Java实现二叉树及其常规操作

😊使用Java实现一个二叉树。

二叉树是一个递归的数据结构,每个节点最多有两个子节点,且有左右之分,分别称为该节点的左右孩子。二叉树是树形结构的一个重要类型,许多实际问题抽象出来的数据结构往往是二叉树形式,因此二叉树显得特别重要,但它的存储结构和算法都较为简单。

二叉树结构以及代码实现很容易,但一定要注意理解递归思想,只要可以很好地理解递归思想,解决二叉树相关问题难度就降低很多了,大家可以参考我博客的内容自己手敲一边代码实现二叉树,收获一定会很大,一起加油😊😊😊

目录

模拟实现二叉树 

定义节点类 

二叉树的初始化

二叉树的先序遍历 

二叉树的中序遍历 

二叉树的后序遍历 

二叉树的节点个数 

求二叉树的叶子节点数 

获取第K层节点个数 

获取二叉树的高度

二叉树的查询 

完整代码 


模拟实现二叉树 

二叉树的结构如下图所示,本篇文章是实现一个字符型的二叉树

定义节点类 

根据二叉树的定义,它有两个节点,且有左右之分,称为左孩子和右孩子,则根据定义,可以定义出二叉树的节点类

class TreeNode {
    public char val;
    public TreeNode left;//左孩子
    public TreeNode right;//右孩子

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

二叉树的初始化

为了方便实现二叉树的操作,首先手动初始化一棵二叉树,二叉树包含A、B、C、D、E、F、G、H八个节点,具体结构如下图所示

具体代码如下: 

    public TreeNode creteTree() {
        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;//根节点
    }

二叉树的先序遍历 

根据定义,二叉树的先序遍历顺序为:根节点->左孩子->右孩子,则根据先序遍历顺序,可以得到上述初始化的二叉树先序遍历顺序为:ABDEHCFG

具体代码如下

    // 先序遍历
    void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }

二叉树的中序遍历 

二叉树的中序遍历顺序为:左孩子->根节点->右孩子,根据该遍历顺序,可以得出上述初始化二叉树的中序遍历顺序为:DBEHAFCG

具体代码如下: 

    // 中序遍历
    void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }

二叉树的后序遍历 

二叉树的后序遍历顺序为:左孩子->右孩子->根节点,根据该遍历顺序,可以得出上述初始化二叉树的后序遍历顺序为:DHEBFGCA

具体代码如下

    // 后序遍历
    void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val + " ");
    }

二叉树的节点个数 

求二叉树的节点个数有两种方式:一种是遍历思路,另一种思路是子问题思路。

遍历思路

定义一个全局变量count,用来记录树中的节点个数,利用递归依次遍历二叉树,求出节点个数.

    public static int count = 0;//记录节点个数

    // 获取树中节点的个数
    public void size1(TreeNode root) {
        if (root == null) {
            return;
        }
        count++;
        size1(root.right);
        size1(root.left);
    }

子问题思路 

利用递归思想不遍历,将整个树分为若干的小树,来求出二叉树的节点个数.节点数为左子树节点 + 右子树节点 + 1. 

    public int size2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        //root不为空
        int tmp = size2(root.left) + size2(root.right) + 1;
        return tmp;
    }

求二叉树的叶子节点数 

叶子节点:度为0的节点称为叶子节点,即该节点无左右孩子.

求二叉树的叶子节点数依旧有遍历和分为子问题两种思路。

遍历思想

定义全局变量num,用来记录叶子节点个数,依次遍历该二叉树,如果该节点的左孩子为空且右孩子为空,则num + 1,具体代码如下:

    // 获取叶子节点的个数  遍历思路
    public static int num = 0;

    void getLeafNodeCount1(TreeNode root) {
        if (root == null) {
            return;
        }
        if (root.left == null && root.right == null) {
            num++;
        }
        getLeafNodeCount1(root.left);
        getLeafNodeCount1(root.right);
    }

子问题思想: 

    // 获取叶子节点的个数  子问题
    int getLeafNodeCount2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        return getLeafNodeCount2(root.left) + getLeafNodeCount2(root.right);
    }

获取第K层节点个数 

获取第k层节点,即求的是当k等于1时,有多少个节点,例如需要求出第三层的节点个数,二叉树的结构如下图所示,k从3开始,当k = 1时,即处在第三层,求出该层有多少个节点即可.

具体代码实现: 

    // 获取第K层节点的个数
    int getKLevelNodeCount(TreeNode root, int k) {
        if (root == null) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        return getKLevelNodeCount(root.right, k - 1) + getKLevelNodeCount(root.left, k - 1);
    }

获取二叉树的高度

要求出二叉树的高度,即求出左子树的高度,再求出右子树的高度,判断哪个高,如果左子树高,则左子树的高度+1即为该二叉树的高度.

具体代码实现

    // 获取二叉树的高度
    int getHeight(TreeNode root){
        if(root == null) {
            return 0;
        }
        int leftH = getHeight(root.left);
        int rightH = getHeight(root.right);
        return leftH > rightH ? leftH+1 : rightH+1;
    }

二叉树的查询 

二叉树的查询利用遍历的思想,以递归的方式实现,首先判断根节点的值是否为待查值,如果不是则依次访问左子树和右子树,如果找到,则返回该节点,如果未找到则返回null.

具体代码实现

    // 检测值为value的元素是否存在
    TreeNode find(TreeNode root, char val) {
        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        TreeNode ret = find(root.left, val);
        if (ret != null) {
            return ret;
        }

        ret = find(root.right, val);
        if (ret != null) {
            return ret;
        }
        return null;
    }

完整代码 

class TreeNode {
    public char val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(char val) {
        this.val = val;
    }
}
public class TestBinaryTree {


    public TreeNode creteTree() {
        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;//根节点
    }


    // 前序遍历
    void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }

    // 中序遍历
    void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }

    // 后序遍历
    void postOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val + " ");
    }

    public static int count = 0;

    // 获取树中节点的个数         遍历思路:
    public void size1(TreeNode root) {
        if (root == null) {
            return;
        }
        count++;
        size1(root.right);
        size1(root.left);
    }

    //获取树中节点的个数     子问题思路
    public int size2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        //root不为空
        int tmp = size2(root.left) + size2(root.right) + 1;
        return tmp;
    }


    // 获取叶子节点的个数  遍历思路
    public static int num = 0;

    void getLeafNodeCount1(TreeNode root) {
        if (root == null) {
            return;
        }
        if (root.left == null && root.right == null) {
            num++;
        }
        getLeafNodeCount1(root.left);
        getLeafNodeCount1(root.right);
    }

    // 获取叶子节点的个数  子问题
    int getLeafNodeCount2(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        return getLeafNodeCount2(root.left) + getLeafNodeCount2(root.right);
    }

    // 获取第K层节点的个数
    int getKLevelNodeCount(TreeNode root, int k) {
        if (root == null) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        return getKLevelNodeCount(root.right, k - 1) + getKLevelNodeCount(root.left, k - 1);
    }

    // 获取二叉树的高度
    int getHeight(TreeNode root){
        if(root == null) {
            return 0;
        }
        int leftH = getHeight(root.left);
        int rightH = getHeight(root.right);
        return leftH > rightH ? leftH+1 : rightH+1;
    }

    // 检测值为value的元素是否存在
    TreeNode find(TreeNode root, char val) {
        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        TreeNode ret = find(root.left, val);
        if (ret != null) {
            return ret;
        }

        ret = find(root.right, val);
        if (ret != null) {
            return ret;
        }
        return null;
    }
}

 

 

 

  • 12
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值