数据结构之二叉树及面试题讲解(一)

简介: 数据结构之二叉树及面试题讲解(一)

💕"从前种种譬如昨日死;从后种种譬如今日生"💕

作者:Mylvzi

文章主要内容:数据结构之二叉树及面试题讲解

一.概念

1.树的定义

 树是一种非线性的数据结构,是由n个结点组成的一种非线性集合;之所以叫做树,是因为他看起来像一颗倒挂的树,也就是根朝上,叶子朝下,一颗二叉树具有以下特征

  • 有一个特殊节点--根节点  一颗二叉树有且仅有一个根节点
  • 树是递归定义的

2.树与非树

 如何判断一棵树是否是树呢?可以通过以下几个方式

  • 除根节点外,其余结点有且仅有一个父节点
  • 一棵树如果有n个结点,则一定有n-1条边
  • 子树是不相交的

3.树的相关概念

  • 度:某个结点的子结点个数就叫做该节点的度  比如B结点的度就是2,因为其有两个子节点
  • 树的度:指的是结点度的最大值   如图A结点的度是3,所以树的度就是3
  • 叶子节点(终端节点):没有子节点的结点  比如E,F,G
  • 祖先节点:所有节点的父节点  就是根节点  本图中A结点时祖先节点
  • 父节点:结点的前驱结点就是父节点,也叫做双亲结点  B是E,F的父节点
  • 孩子节点:与父结点相对
  • 树的高度:树的层次的最大值就是树的高度  如图层次是三,所以树的高度就是3
  • 树的以下概念只需了解,在看书时只要知道是什么意思即可:
  • 非终端结点或分支结点:度不为0的结点;
  • 兄弟结点:具有相同父结点的结点互称为兄弟结点;
  • 堂兄弟结点:双亲在同一层的结点互为堂兄弟;
  • 森林:由m(m>=0)棵互不相交的树组成的集合称为森林

4.树的表示形式(了解)

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,实际中树有很多种表示方式,如:双亲表示法, 孩子表示法、孩子双亲表示法、孩子兄弟表示法等等。我们这里就简单的了解其中最常用的孩子兄弟表示法。

class Node {
int value; // 树中存储的数据
Node firstChild; // 第一个孩子引用
Node nextBrother; // 下一个兄弟引用
}

二. 二叉树(重点)

1.概念

 二叉树是树形结构的一种,二叉树就是度<= 2的的树

二叉树是由以下几种情况组成

2.两种特殊的二叉树

  1. 满二叉树: 一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。也就是说,如果一棵 二叉树的层数为K,且结点总数是 2^k - 1,则它就是满二叉树。
  2. 完全二叉树: 完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n 个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完 全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。
  3. 完全二叉树就是从上到下,从左到右依次存放结点的树

3.二叉树的性质(重点 )

  • 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有(2^i - 1) (i>0)个结点
  • 若规定只有根结点的二叉树的深度为1,则深度为K的二叉树的最大结点数是(2^k - 1) (k>=0)推导:等比数列的求和公式推导而成
  • 具有n个结点的完全二叉树的深度k 为 Log(n+1)向 上取整
  • 对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1  也就是叶子节点的个数一定比度为2的结点的个数多一

这个性质经常作为考试题目,会结合结点数目的奇偶性以及完全二叉树来出题

如果结点数是2N,则n1的个数一定是1

如果结点数是2N+1,则n1的个数一定是0

4.二叉树的存储

 二叉树的存储结构分为:顺序存储和链式存储

 顺序存储的底层其实是"堆"这种数据结构的实现,也就是二叉搜索树

 我们以链式的存储结构进行讲解

二叉树的链式存储结构是通过一个一个结点实现的,最常用的表示方法是左右孩子表示法,即每个节点存储左右孩子结点

定义结点内部类

static class TreeNode {
        public int val;
        public TreeNode lChild;// 左孩子
        public TreeNode rChild;// 右孩子
        public TreeNode(char val) {
            this.val = val;
        }
    }

手动插入结点

public TreeNode create() {
        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.lChild = B;
        A.rChild = C;
        B.lChild = D;
        B.rChild = E;
        C.lChild = F;
        C.rChild = G;
        E.rChild = H;
        return A;
    }

2.二叉树的遍历

 遍历是二叉树的一个很重要的操作,二叉树作为一种存储数据的结构,在我们获取数据的时候需要遍历整棵二叉树,直到拿到我们所需要的数据,不同的遍历方式也会带来不同的效率,二叉树常见的遍历方式有:

  • 前序遍历preOrder  根左右
  • 中序遍历inOrder  左根右
  • 后序遍历postOrder 左右根
  • 层序遍历levelOrder 从上至下从左至右依次遍历每一个结点

遍历操作最核心的思路就是"子问题思路"和递归的思想,下面进行遍历的代码实现

把整棵二叉树想象为只有一个根节点和两个孩子节点的树,很多二叉树的问题就容易解决

要谨记,二叉树有两种,空树和非空树,任何情况下都不要忘记空树的情况

1,前序遍历

// 前序
    public void preOrder(TreeNode root) {
        // 空树直接返回
        if(root == null) return;
        System.out.print(root.val+" ");
        // 打印完根节点再去访问左孩子和右孩子
        preOrder(root.lChild);
        preOrder(root.rChild);
    }

力扣题目

https://leetcode.cn/problems/binary-tree-preorder-traversal/submissions/

代码实现

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
// 空树直接返回
        if(root == null) return list;
        list.add(root.val);
        // 遍历左子树
        List<Integer> leftTree = preorderTraversal(root.left);
        list.addAll(leftTree);
        // 遍历右子树
        List<Integer> rightTree = preorderTraversal(root.right);
        list.addAll(rightTree);
        return list;
    }

2.中序遍历

// 中序
    public void inOrder(TreeNode root) {
// 空树 直接返回
        if(root == null) return;
        inOrder(root.lChild);
        System.out.print(root.val+" ");
        inOrder(root.rChild);
    }

https://leetcode.cn/problems/binary-tree-inorder-traversal/submissions/

代码实现

public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
// 空树 直接返回
        if(root == null) return list;
        // 遍历左子树
        List<Integer> leftTree = inorderTraversal(root.left);
        list.addAll(leftTree);
        list.add(root.val);
        // 遍历右子树
        List<Integer> rightTree = inorderTraversal(root.right);
        list.addAll(rightTree);
        return list;
    }

数据结构之二叉树及面试题讲解(二)+https://developer.aliyun.com/article/1413554

目录
相关文章
|
4月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
198 3
|
7月前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
195 10
 算法系列之数据结构-二叉树
|
9月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
186 12
|
9月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
166 10
|
9月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
262 3
|
10月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
11月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
260 4
|
11月前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
693 8
|
12月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
134 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
11月前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet

热门文章

最新文章