文章目录
这篇主要是讲解二叉树的理论,代码具体实现请看这篇文章: 【代码随想录刷题】二叉树的实现java版
1.树
1.1 简述
树是一种抽象数据类型(ADT),是一种非线性数据结构。它由n(n>0)个有限节点通过连接它们的边组成一个有层次关系的集合。它是根朝上,叶朝下。
1.2 相关概念
- 1.节点的度:一个节点含有的子树的个数。
如:A节点的度为2,B节点的度为1- 2.树的度:一棵树中,最大的节点的度。
如:该树的度为4- 3.叶子节点或终端节点:度为0的结点。
如:D J K M N G P都是叶子结点- 4.双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点。
如:节点C的父节点为B- 5.孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点。
如:节点M是结点C的子节点- 6.根节点:一颗树中,没有双亲节点的节点称为根节点。
如:结点A为根节点- 7.节点的层次:从根开始定义,根为第1层,根的子节点为第二层,以此类推。
如:该树有4层- 8.节点的深度:某节点层次是第几层,则它的深度是多少。
如:节点A深度为1,节点H深度为3- 9.树的高度:树中节点的最大层次。
如:该树的高度为4- 10.非终端节点或分支节点:度不为0的节点。
如:节点A B C E H- 11.兄弟节点:父亲节点相同的节点互称为兄弟节点。
如:节点D J K M互为兄弟节点- 12.节点的祖先:从根节点到该节点所经过分支上的所有节点都称为该节点的祖先。
如:节点D的祖先是节点A B C- 13.子孙:以某节点为根的子树中,任意节点都称为该节点的子孙。
如:该树中除 A节点其它节点都是 TA节点的子孙- 14.森林:由 m(m>=0)棵互不相交的树的集合称为森林。
1.3 树的存储形式
-
存储方法主要有:双亲表示法、孩子表示法、孩子兄弟表示法
-
常用的是孩子兄弟表示法
class Node{
int val; // 存储树中的数据
Node firstChild;
Node nextBrother;
}
1.4 树的应用
我们电脑的文件系统管理和树的结构很相似,尤其是 linux 系统。
2.二叉树的定义
二叉树: 是 n 个有限元素的集合,该集合或者为空,或者是由一个根节点加上两棵不相交的,被分别称为左子树和右子树的二叉树组成。
特点:
- 1.当集合为空时,该二叉树称为空二叉树
- 2.在二叉树中,一个元素也称为一个节点
- 3.每个节点最多有两棵子树,即二叉树不存在度大于2的节点
- 4.二叉树的子树有左右之分,其子树的次序不能颠倒,因此二叉树是有序树
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
public TreeNode() {
}
public TreeNode(int val) {
this.val = val;
}
public TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
3.二叉树的种类
在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树。
3.1 满二叉树
满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。
这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个节点的二叉树。
3.2 完全二叉树和非完全二叉树
完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。
3.3 二叉搜索树
3.1和3.2中介绍的树,都没有数值的,而二叉搜索树是有数值的了,二叉搜索树是一个有序树。
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树。
下面这两棵树都是搜索树:
3.4 平衡二叉搜索树
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
如图:
最后一棵 不是平衡二叉树,因为它的左右两个子树的高度差的绝对值超过了1。
4.二叉树的存储方式
-
二叉树可以链式存储,也可以顺序存储。
-
那么链式存储方式就用指针, 顺序存储的方式就是用数组。
-
顾名思义就是顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在各个地址的节点串联一起。
链式存储如图:
顺序存储:
那么,用数组存储二叉树,如何遍历呢?
如果父节点的数组下标是 i ,那么它的左孩子就是 2 * i+1,右孩子就是2 * i+2 。
但是链式表示的二叉树,更有利于我们理解,所以我们一般是用链式来存储二叉树。
5.二叉树的遍历方式
深度优先遍历
- 前序遍历(递归,迭代) 节点顺序:根左右
- 中序遍历(递归,迭代) 节点顺序:左根右
- 后序遍历(递归,迭代) 节点顺序:左右根
广度优先遍历
- 层次遍历(迭代)
示例:
参考文章: