Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【数据结构与算法】9. 二叉树的基本操作

【数据结构与算法】9. 二叉树的基本操作

作者头像
爱敲代码的小杨.
发布于 2024-10-15 01:23:15
发布于 2024-10-15 01:23:15
10400
代码可运行
举报
文章被收录于专栏:JavaJava
运行总次数:0
代码可运行

前面我们了解了 二叉树的基本概念,以及二叉树的三种遍历方式,今天我们来学习二叉树的基本操作

1. 二叉树的基本操作

1.1 获取树中节点的个数

实现方法:

  1. 判断根节点是否为空(如果根节点为空则这棵树为空树),返回0
  2. 不为空,返回左子树的个数+右子树的个数+根节点

size方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 获取树种节点的个数
     * 子问题
     * @param root
     * @return
     */
    public int size(TreeNode root) {
        // 空树
        if (root == null) {
            return 0;
        }
        // 左子树的个数+右子树的个数+1
        int nums = size(root.left) + size(root.right) + 1;
        return nums;
    }

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Test {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.createTree(); // 创建二叉树
        int num = binaryTree.size(root); // 调用size方法
        System.out.println("二叉树的节点个数:" + num);
    }
}

1.2 获取叶子节点的个数

实现方法:

  1. 判断根节点是否为空(如果根节点为空则这棵树为空树),返回0
  2. 如果不为空,根节点左子树和右子树为空,则返回1(只有根节点)
  3. 如果都不为空,则返回左子树的个数+右子树的个数

getLeafNodeCount方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 获取叶子节点的个数
     * @param root
     * @return
     */
    public int getLeafNodeCount(TreeNode root) {
        // 空树
        if (root == null) {
            return 0;
        }
        // 只有头节点
        if (root.left == null && root.right == null) {
            return 1;
        }
        int i = getLeafNodeCount(root.left);   // 左子树的个数
        int j = getLeafNodeCount(root.right);  // 右子树的个数
        return (i + j);
    }

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Test {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.createTree(); // 创建二叉树
        int num = binaryTree.getLeafNodeCount(root); // 
        System.out.println("叶子节点的个数" + num);
    }
}

1.3 获取第K层节点的个数

实现方法:

  1. 判断根节点是否为空(如果根节点为空则这棵树为空树),返回0
  2. 不为空,如果层数为1并且根节点不为空,则返回1
  3. 如果层数大于1,则返回根节点的左子树和右子树的k-1层之和

getKLevelNodeCount方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 获取第k层节点的个数
     * @param root 树的头节点
     * @param k 第k层
     * @return
     */
    public int getKLevelNodeCount(TreeNode root, int k) {
        if (root == null) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        int i = getKLevelNodeCount(root.left, k - 1);
        int j = getKLevelNodeCount(root.right, k - 1);
        return i + j;
    }

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Test {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.createTree(); // 创建二叉树
        int k = 2;
        int num = binaryTree.getKLevelNodeCount(root, k);
        System.out.println("第" + k +"层的节点个数:" + num);
    }
}

1.4 获取二叉树的高度

实现方法:

  1. 判断根节点是否为空(如果根节点为空则这棵树为空树),返回0
  2. 如果不为空,则计算根节点的左子树和右子树的高度
  3. 返回子树的最高层+1

getHeight方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 获取二叉树的高度
     * @param root
     * @return
     */
    public int getHeight(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int i = getHeight(root.left); // 左子树的高度
        int j = getHeight(root.right); // 右子树的高度
        return Math.max(i, j) + 1;
    }

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Test {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.createTree(); // 创建二叉树
        int height = binaryTree.getHeight(root);
        System.out.println("二叉树的高度:" + height);
    }
}

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

实现方法:

  1. 判断根节点是否为空(如果根节点为空则这棵树为空树),返回null
  2. 如果不为空,判断根节点的值是否为要查找的值;如果是,则返回根节点的值;
  3. 递归在左子树中查找值,如果在左子树中找到了值,则返回找到的节点;
  4. 如果没在左子树找到值,则递归在右子树中查找值,如果在右子树中找到了值,则返回找到的节点;
  5. 如果左右子树都没有找到值,则返回null

find方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 判断val是否存在
     * @param root 头节点
     * @param val 要查找的值
     * @return
     */
    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;
    }

测试代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Test {
    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        BinaryTree.TreeNode root = binaryTree.createTree();

        BinaryTree.TreeNode num = binaryTree.find(root, 'A');
        if (num == null) {
            System.out.println("没有找到要查找的值");
            return;
        }
        System.out.println(num.val);
    }
}

1.6 完整代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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');
        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 + " ");
    }

    /**
     * 获取树种节点的个数
     * 子问题
     * @param root
     * @return
     */
    public int size(TreeNode root) {
        // 空树
        if (root == null) {
            return 0;
        }
        // 左子树的个数+右子树的个数+1
        int nums = size(root.left) + size(root.right) + 1;
        return nums;
    }

    /**
     * 获取叶子节点的个数
     * @param root
     * @return
     */
    public int getLeafNodeCount(TreeNode root) {
        // 空树
        if (root == null) {
            return 0;
        }
        // 只有头节点
        if (root.left == null && root.right == null) {
            return 1;
        }
        int i = getLeafNodeCount(root.left);   // 左子树的个数
        int j = getLeafNodeCount(root.right);  // 右子树的个数
        return (i + j);
    }

    /**
     * 获取第k层节点的个数
     * @param root 树的头节点
     * @param k 第k层
     * @return
     */
    public int getKLevelNodeCount(TreeNode root, int k) {
        if (root == null) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        int i = getKLevelNodeCount(root.left, k - 1);
        int j = getKLevelNodeCount(root.right, k - 1);
        return i + j;
    }

        /**
         * 获取二叉树的高度
         * @param root
         * @return
         */
        public int getHeight(TreeNode root) {
            if (root == null) {
                return 0;
            }
            int i = getHeight(root.left); // 左子树的高度
            int j = getHeight(root.right); // 右子树的高度
            return Math.max(i, j) + 1;
        }

    /**
     * 判断val是否存在
     * @param root 头节点
     * @param val 要查找的值
     * @return
     */
    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;
    }
}

2. 二叉树相关OJ题

奋笔疾书中…

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
二叉树oj以及前中后序非递归写法
给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。
始终学不会
2023/10/17
1980
二叉树oj以及前中后序非递归写法
【数据结构】二叉搜索树BSTree
(注意:不能插入重复的元素,并且每次插入都是要定位到空节点的位置;我们先定义一个 cur从root开始,比较元素的大小:若插入的元素比当前位置元素小就往左走,比当前位置元素大就往右走,直到为空,相等就不能插入了;同时定义一个parent去记录当前 cur的前一个位置,最后判断cur是parent的左子树还是右子树即可)
平凡的人1
2023/10/15
2450
【数据结构】二叉搜索树BSTree
【C++】二叉搜索树
二叉搜索树又称二叉排序树,可以简写成 BST,它或者是一棵空树,或者是具有以下性质的二叉树:
YoungMLet
2024/03/01
1220
【C++】二叉搜索树
【二叉树进阶】leetcode&牛客 二叉树进阶面试题
所以,解这道题之前,我们可以先来分析一下,哪些情况需要省略空括号,哪些情况不能省略 那对照着图我们很容易得出,括号的处理应该是这样的:
YIN_尹
2024/01/23
1510
【二叉树进阶】leetcode&牛客 二叉树进阶面试题
C++【二叉树进阶试题】
这是一篇关于 二叉树 题解博客,主要包含以下题目,可根据当前文章中的目录随意跳转查看
北 海
2023/07/01
2520
C++【二叉树进阶试题】
二叉树OJ题(C++实现)
主要思路是借助一个队列,将每一层的数据以size统计,当size为0时说明该层数据已经输入完,将这一层的数据传入vector中,再通过push_back 传入 vector< vector< int >中
lovevivi
2023/10/16
1870
二叉树OJ题(C++实现)
【Leetcode】二叉树的最近公共祖先,二叉搜索树转换成排好序的双向链表,前序遍历与中序遍历构造二叉树
观察上图,节点1和节点4的最近公共祖先是3,这是不是很像相交链表的问题,关于相交链表,曾经我在另一篇文章里写到过,读者可以参考:反转链表 合并链表 相交链表
aosei
2024/01/23
1750
【Leetcode】二叉树的最近公共祖先,二叉搜索树转换成排好序的双向链表,前序遍历与中序遍历构造二叉树
【代码随想录】二刷-二叉树
二叉树中章节中,相对于迭代,递归有时候会更好理解,部分题用到了马上要刷的回溯算法。
半生瓜的blog
2023/05/13
8430
【代码随想录】二刷-二叉树
种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林
树是我们计算机中非常重要的一种数据结构,同时使用树这种数据结构,可以描述现实生活中的很多事物,例如家 谱、单位的组织架构、等等。 树是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就 是说它是根朝上,而叶朝下的。
看、未来
2020/08/25
1.1K0
种树:二叉树、二叉搜索树、AVL树、红黑树、哈夫曼树、B树、树与森林
为实习准备的数据结构(4)-- 二叉树
==特别标注:如果二叉树中有相同值元素的存在,那么有极大概率还原失败,下面中、后序遍历也是==
看、未来
2021/03/17
3780
数据结构与算法(3)——树(二叉、二叉搜索树)树LeetCode相关题目整理
树是一种类似于链表的数据结构,不过链表的结点是以线性方式简单地指向其后继结点,而树的一个结点可以指向许多个结点;数是一种典型的非线性结构;树结构是以表达具有层次特性的图结构的一种方法;
我没有三颗心脏
2018/07/24
1.1K0
数据结构与算法(3)——树(二叉、二叉搜索树)树LeetCode相关题目整理
N叉树问题-LeetCode 429、589、590、105、106(构建二叉树,N叉树遍历)
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。 例如,给定一个 3叉树 :
算法工程师之路
2019/11/26
1.2K0
N叉树问题-LeetCode 429、589、590、105、106(构建二叉树,N叉树遍历)
C++【二叉搜索树】
时隔多日,又回到了二叉树的学习中,在 C++ 进阶中,我们首先要学习 二叉搜索树,重新捡起二叉树的相关知识,然后会学习 AVL 树 及 红黑树,最后会用红黑树封装实现库中的 set 和 map,作为 C++ 进阶中的难度最高峰,整个学习过程非常艰辛,但 关关难过关关过,让我们先从比较简单的 二叉搜索树 开始学习
北 海
2023/07/01
1610
C++【二叉搜索树】
LeetCode——遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例 1:
有礼貌的灰绅士
2023/04/17
2390
LeetCode——遍历序列构造二叉树
【C++】二叉搜索树
1. 搜索树的结点的定义也比较简单,每个结点都有左右子树和自身存储的_key值,_key就是利用搜索树进行搜索时的数据。
举杯邀明月
2023/04/12
2730
【C++】二叉搜索树
二叉树:构造二叉树登场!
首先回忆一下如何根据两个顺序构造一个唯一的二叉树,相信理论知识大家应该都清楚,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来在切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。
代码随想录
2020/10/10
8141
二叉树:构造二叉树登场!
每日一题(根据二叉树创建字符串,二叉树层序遍历,二叉树的层序遍历 II)
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
雪芙花
2022/10/31
1620
算法:分治
分治是一种将大问题分解成相同任务的小问题的方法,常见的分治思想之一就是归并排序(mergeSort)
用户3578099
2022/04/18
1K0
算法:分治
C++二叉搜索树与KV模型
二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树
有礼貌的灰绅士
2023/04/12
4050
C++二叉搜索树与KV模型
二叉搜索树
让编译器提供个默认生成的就可以了,如果不写这个,又写了拷贝构造,编译器就不会自己自动生成了。
芝士就是菜
2023/04/20
2600
二叉搜索树
推荐阅读
相关推荐
二叉树oj以及前中后序非递归写法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验