Java数据结构第十三期:走进二叉树的奇妙世界(二)

专栏:数据结构(Java版)

个人主页:手握风云

目录

一、二叉树的遍历

[1.1. 前序遍历](#1.1. 前序遍历)

[1.2. 中序遍历](#1.2. 中序遍历)

[1.3. 后序遍历](#1.3. 后序遍历)

[1.4. 完整代码](#1.4. 完整代码)

二、二叉树的基本操作

[2.1. 获取树中结点个数](#2.1. 获取树中结点个数)

[2.1. 获取叶子结点个数](#2.1. 获取叶子结点个数)

[2.3. 获取第k层结点的个数](#2.3. 获取第k层结点的个数)

[2.4. 获取二叉树的高度](#2.4. 获取二叉树的高度)

[2.5. 检测值为value的元素是否存在](#2.5. 检测值为value的元素是否存在)


一、二叉树的遍历

1.1. 前序遍历

前序遍历又叫先根遍历。每一个节点的遍历顺序都是按照"根------>左子树------>右子树"的顺序来遍历,每遇到一个新的结点都看作是一棵新的树。如果遇到空,则递归回上一个节点。A的右子树遍历过程也如下,所以前序遍历的结果为"ABDCEF"。

1.2. 中序遍历

中序遍历的顺序为"左子树------>根------>右子树",遇到一个结点,先去遍历左子树,如果该节点的根为空,才能递归回来进行打印。所以中序遍历的结果为"DBAECF"。

1.3. 后序遍历

后序遍历的顺序为"左子树------>右子树------>根",遍历过程与上面两种都差不多,这里不再多说。后序遍历的顺序为"DBEFCA"。

1.4. 完整代码

java 复制代码
public class BinaryTree {
    static class TreeNode{
        public char val;
        public TreeNode left;
        public TreeNode right;

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

    public TreeNode CreateTree(){
        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');

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

        return A;
    }

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

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

    public void PostOrder(TreeNode root){//后序遍历
        if(root == null){
            return;
        }
        PostOrder(root.left);
        PostOrder(root.right);
        System.out.print(root.val+" ");
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.CreateTree();
        System.out.print("前序遍历:");
        binaryTree.PrevOrder(root);
        System.out.println();
        System.out.print("中序遍历:");
        binaryTree.InOrder(root);
        System.out.println();
        System.out.print("后序遍历:");
        binaryTree.PostOrder(root);
    }
}

二、二叉树的基本操作

2.1. 获取树中结点个数

我们先回想以下如何获取链表中的结点个数。我们定义一个ListNode cur变量,当cur不为空时,count递增。同样的,我们上面已经实现了二叉树结点的遍历,我们也只需要再定义一个计数器,只要root不为空,countNode就递增。

java 复制代码
    public void NodeSize(TreeNode root){
        if(root == null){
            return;
        }
        CountSize++;
        NodeSize(root.left);
        NodeSize(root.right);
    }

上面的是遍历思路,还有一种子问题思路。整棵树的结点个数等于左树的结点数和右树的结点数再加一,只要root为空,那么我们就可以结束递归。

java 复制代码
    public int NodeSize2(TreeNode root){
        if(root == null){
            return 0;
        }
        int tmp = NodeSize2(root.left)+NodeSize2(root.right)+1;
        return tmp;
    }

2.1. 获取叶子结点个数

叶子结点就是没有左右子树的结点,递推公式为左子树叶子结点加右子树结点,结束条件为结点的左右子树都为空。

java 复制代码
    //获取叶子结点个数
    public int getLeafNodeCount(TreeNode root){
        if(root == null){
            return 0;
        }else if(root.left == null && root.right == null){
            return 1;
        }else{
            return getLeafNodeCount(root.left)
                    + getLeafNodeCount(root.right);
        }
    }

    public int LeafCount;

    //遍历问题
    public void getLeafNodeCount2(TreeNode root){
        if(root == null){
            return;
        }
        if(root.left == null && root.right == null){
            LeafCount++;
        }
        getLeafNodeCount2(root.left);
        getLeafNodeCount2(root.right);
    }

2.3. 获取第k层结点的个数

比如我们要想获取第3层结点的个数,就要求root.left第2层和root.right的第二层,相当于左树的第一层和右树的第一层。当k=1时,已经找到这一层,此时也是递归的结束条件。

java 复制代码
    //获取第k层结点的个数
    public int getLevelNodeCount(TreeNode root,int k){
        if(root == null){
            return 0;
        }
        if(k == 1){
            return 1;
        }
        return getLevelNodeCount(root.right,k-1) +
                getLevelNodeCount(root.left,k-1);
    }

2.4. 获取二叉树的高度

求二叉树的高度,整棵树的高度等于左子树高度的最大值或者右子树高度的最大值加一,当root为空的时候,高度为0。由于我们不知道是左子树高还是右子树高,所以两边都需要遍历。

java 复制代码
    //获取二叉树的高度
    public int getHeight(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftH = getHeight(root.left);
        int rightH = getHeight(root.right);
        return Math.max(leftH,rightH) + 1;
    }

2.5. 检测值为value的元素是否存在

我们先检查根结点是不是,然后再遍历左子树和右子树,当我们找到了val值,直接返回,不用再递归下面了。

java 复制代码
    // 检测值为value的元素是否存在
    public TreeNode find(TreeNode root,int val){
        if(root == null){
            return null;
        }
        if(root.val == val){
            return root;
        }
        
        TreeNode leftVal = find(root.left,val);
        if(leftVal != null){
            return leftVal;
        }
        
        TreeNode rightVal = find(root.right,val);
        if(rightVal != null){
            return rightVal;
        }
        
        return null;
    }
java 复制代码
public class Solution {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.CreatTree();
        binaryTree.NodeSize(root);
        System.out.println("结点个数:"+binaryTree.CountSize);
        System.out.println("结点个数:"+binaryTree.NodeSize2(root));
        System.out.println("叶子结点个数:"+binaryTree.getLeafNodeCount(root));
        binaryTree.getLeafNodeCount2(root);
        System.out.println("叶子结点个数:"+binaryTree.LeafCount);
        System.out.println("第3层结点个数:"+binaryTree.getLevelNodeCount(root,3));
        System.out.println("二叉树的高度:"+binaryTree.getHeight(root));
    }
}
相关推荐
北域码匠8 小时前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法
Darling噜啦啦7 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠8 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾8 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres8218 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q8 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒8 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
WL学习笔记8 天前
单项不带头不循环链表
数据结构·链表
小糯米6018 天前
JS 数组
数据结构·算法·排序算法
小欣加油8 天前
leetcode3612 用特殊操作处理字符串I
数据结构·c++·算法·leetcode·职场和发展