IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 树形结构(3)(Java语言)——二叉树(2) -> 正文阅读

[数据结构与算法]树形结构(3)(Java语言)——二叉树(2)

二叉树的基本操作

前提条件

节点

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

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

二叉树

public class BinaryTree {
	public TreeNode root;//二叉树的根节点

    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');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');
        root = A;
        A.left = B;
        A.right = C;
        B.left = D;
        B.right = E;
        E.right = H;
        C.left = F;
        C.right = G;
        return root;
    }
}

获取树中节点的个数

方法1

int count = 0;
int size(TreeNode root) {
        if (root == null) {
            return count;
        }
        count++;
        size(root.left);
        size(root.right);
        return count;
    }

我们利用遍历的思路完成size()方法,比如我们用先序遍历整个链表,在遍历过程中,如果节点不为null,那么计数器count就加1,直到遍历完整个链表完成sizeof()方法,但是需要注意的是,在计数器count不能放在方法的内部,否则每次递归都会将count置为0,从而重新计算count。

方法2

int size1(TreeNode root) {
        if (root == null) {
            return 0;
        }
        return size1(root.right) + size1(root.left) + 1;
    }

虽然代码量少但是不容易想到,因为这是采用的子问题解决的,举个例子:
在这里插入图片描述
解决这个节点个数问题,我们可以看作求A节点左树和右树的个数(左树右树是否存在),A左树的个数(0或者1)+A右树的个数(0或者1)+A本身(1)。求A左树的个数又可以由B左树的个数+B右树的个数+1求得,依次递归可以得到节点的个数。

获取叶子节点的个数

方法1

// 获取叶子节点的个数
    int LeafCount = 0;

    int getLeafNodeCount1(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.right == null && root.left == null) {
            LeafCount++;
        }
        getLeafNodeCount1(root.left);
        getLeafNodeCount1(root.right);
        return LeafCount;
    }

跟获取节点个数类似,用遍历的方法解决该问题,当节点为null是返回0;当节点的左右孩子都为null时,证明此时的节点为叶子节点,所以LeafCount++,以此递归完成方法,最后返回LeafCount的值。同样需要注意的是LeafCount需要放到方法的外面,当然LeafCount也可以用static修饰。

方法2

int getLeafNodeCount(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.right == null && root.left == null) {
            return 1;
        }
        
        return getLeafNodeCount(root.right) + getLeafNodeCount(root.left);
    }

同样可以采用子问题的思路解决这个问题,要求出整棵树的叶子节点,我们可以求左子树和右子树的叶子节点的总和,只要满足一个节点的没有左右孩子那么就加上1,最后返回根节点的getLeafNodeCount(root.right)和getLeafNodeCount(root.left)的总和。

获取第K层节点的个数

    int getKLevelNodeCount(TreeNode root, int k) {

        if (root == null || k <= 0) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        return getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.right, k - 1);
    }

举个例子:
在这里插入图片描述
假设我们要求第3层的节点个数,首先就是求A节点往下第三层的节点个数,因此我们可以求A节点左右子树B和C往下2层的节点个数,最后就是求D,E(B的左右子树)F,G(C的左右子树)的往下1层的节点个数(这里的往下1层表示不动的意思),因此递归条件就是当k为1时,返回1,或者root == null和k <= 0返回0。最后返回getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.right, k - 1)的值。

获取二叉树的高度

int getHeight1(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = getHeight1(root.left);
        int rightHeight = getHeight1(root.right);
        return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
    }

举个例子:
在这里插入图片描述
我们仍用子问题的思路求解,在求这棵树的高度时,我们需要求A的左右子树(B和C)的高度,让B树和C树的最大值加上1就是A树的高度,通理,求B树的高度就是求D树和E树的最大值加上1就是B树的高度,以此递归。当root为null时返回0,用leftHeight和rightHeight分别计算出root左右子树的高度,最后以三目运算符计算出leftHeight和rightHeight的最大值,将最大值加上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;
    }

举个例子:
在这里插入图片描述
假设我们要在这个二叉树上找“E”,我们直到会有3种情况,第一,root为null,此时返回null,第二,root.val和val值相等,那么返回root,第三,没有找到val值,并且root也不为null,那么此时我们需要先向root的左子树寻找,如果左子树有相应的val值,那么返回root,否则往root的右子树寻找,如果有val值返回root,如果右子树也没有val值,那么最后返回null值。

判断一棵树是不是完全二叉树

boolean isCompleteTree(TreeNode root){
    if (root == null){
        return true;
    }
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (queue.peek() != null){
        queue.offer(queue.peek().left);
        queue.offer(queue.peek().right);
        queue.poll();
    }
    while (queue.poll() == null){
        if (queue.isEmpty()){
            return true;
        }
    }
    return false;
}

判断一棵树是否为完全二叉树需要我们用到队列来解决,举个例子:
在这里插入图片描述
我们知道这个这个树不是完全二叉树,那么思路是什么样的呢?
首先,我们将A节点放入队列中去。
在这里插入图片描述
然后将队头元素A弹出,放入A左右孩子节点(B和C)。
在这里插入图片描述
同样的,将队头元素B弹出,放入B左右孩子节点(D和E)。
在这里插入图片描述
同理,C节点也是如此。

在这里插入图片描述
将队头元素D弹出时,放入D的左右孩子节点(null和null)。
在这里插入图片描述
如此循环,当队头元素为null时跳出循环,此时情况如下:
在这里插入图片描述
此时队头为null,每次弹出一个队头元素,如果队头为null进入循环,判断此时的队列是否为空,如果为空,返回true,当弹出的队头元素不为null时,则不进入循环直接返回false。我们可以看到上述队列中当弹出队头三次时,遇到了H节点,并不为null,因此该树并不是完全二叉树。
注意: 这当中有一个非常容易错的点在于队列必须先放入左节点,在放入右节点,如果先放入右节点,然后在放入左节点很容易出现bug导致代码报错。
好了,关于二叉树的基本操作就是这么多,这些基本操作对于理解二叉树的性质和递归思想有着非常好的作用,如果有什么问题或者想法欢迎各位私信和评论,也希望这篇博客能够给各位带来帮助,谢谢大家!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-02-09 20:57:15  更:2022-02-09 20:57:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 18:38:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码