目录
1. 若规定根结点的层数为1,则一棵非空二叉树的第 i 层上最多有编辑(i>0)个结点。
2. 若规定只有根结点的二叉树的深度为1,则深度为 k 的二叉树的最大结点数是编辑(k>=0)
3. 对任何一棵二叉树,如果其叶子结点个数为 n0 ,度为 2 的非叶子结点个数为 n2 ,则有 n0 = n2 + 1。
4. 具有 n 个结点的完全二叉树的深度 k 为 log₂(n + 1) 向上取整。
5. 对于具有 n 个结点的完全二叉树,根据结点序号得出左右孩子序号以及双亲结点序号。
一、基本规律
二叉树(Binary Tree):最多有2个子树的树形结构,是一棵有序树(孩子的左右顺序很重要)。其中左边的孩子称为左孩子(左子树),右边的孩子称为右孩子(右子树)。
下图中,A结点:根结点;以B结点作为根结点:左子树;一个结点都没有(没有右孩子):空树(右子树)。
1. 若规定根结点的层数为1,则一棵非空二叉树的第 i 层上最多有(i>0)个结点。
2. 若规定只有根结点的二叉树的深度为1,则深度为 k 的二叉树的最大结点数是(k>=0)
发现是一个 a1 = 1,q = 2 ,n = 4的一个等比数列,即求等比数列的和。
所以结点数为 15。总结规律得任何一个二叉树,q = 2 且a1 = 1 ,而层数 k 就为 n。所以可以得出结点数为 。(满二叉树即为最大结点数的情况)
3. 对任何一棵二叉树,如果其叶子结点个数为 n0 ,度为 2 的非叶子结点个数为 n2 ,则有 n0 = n2 + 1。
假设在一棵二叉树中,一共有 n0 个为度为 0 的结点,n1 个度为 1 的结点,n2 个度为 2 的结点。由于二叉树中所有结点的度只能是0、1、2,所以,整棵二叉树的结点个数 n = n0 + n1 + n2。
利用边的关系。度为 2 的有 2 条边,度为 1 的有 1 条边,度为 0 的有 0 条边。 所以总的边数为:0 * n0 + 1 * n1 + 2 * n2。
又因为每个结点都有一个双亲结点,即每一个结点都有一条连接双亲结点的边(根结点除外),所以总的边数为:结点个数 - 1。
所以可以得出:0 * n0 + 1 * n1 + 2 * n2 = n0 + n1 + n2 - 1
解得:n0 = n2 + 1
4. 具有 n 个结点的完全二叉树的深度 k 为 log₂(n + 1) 向上取整。
n 个结点的完全二叉树 = 一棵满二叉树 + 剩余的结点构成 1 层(这层可能没有,则该完全二叉树就是满二叉树)。
当为满二叉树时,,则 k = log₂ (n + 1) 。
当有剩余结点的完全二叉树的情况时, k = log₂ (n + 1) 计算出来的 k 一定为小数,则最终 k 为其整数部分 + 1 后的值。
5. 对于具有 n 个结点的完全二叉树,根据结点序号得出左右孩子序号以及双亲结点序号。
对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有结点从 0 开始编号,则对于序号为 i 的结点有:
- 若 i > 0,双亲序号:(i - 1)/ 2 ;i = 0 为根结点,无双亲结点。
- 若 2i + 1 < n,左孩子序号:2i + 1,否则无左孩子。
- 若 2i + 2 < n,右孩子序号:2i + 2,否则无右孩子。
二、二叉树的遍历
由于二叉树是非线性结构,要遍历的话必须是线性结构,所以分为两种遍历方式:深度优先遍历和广度优先遍历。
1. 深度优先遍历
(1)前序遍历:根 -> 左 -> 右 (从双亲结点过来)
经过根 按照相同方式遍历左子树 按照相同方式遍历右子树
例如图中:前序遍历为 A B D E H C F G
第二种理解方法:前序遍历是第一次经过(从双亲过来)根结点就进行输出(操作),如图所示:
图中代表一个结点,遍历的过程中会经过这个结点 3 次,分别是从双亲结点过来(1、6)、从左孩子过来(2、3)、从右孩子过来(4、5),为了方便表示分别标位1、2、3、4、5、6。当为前序遍历时,在第一次经过(从双亲过来)时就进行输出该结点。
根据第二种思路,从第一次(双亲结点)过来时就进行输出(操作),则前序遍历:A B D E H C F G。
(2)中序遍历:左 -> 根 -> 右 (从左孩子过来)
按照相同方式遍历左子树 经过根 按照相同方式遍历右子树
例如图中中序遍历:D B E H A F C G。
第二种理解方法: 第二次经过结点时(从左孩子过来)进行输出(操作)。
(3)后序遍历:左 -> 右 -> 根 (从右孩子过来)
按照相同方式遍历左子树 按照形同方式遍历右子树 操作根
例如图中后序遍历:D H E B F G C A。
第二种理解方法:第三次经过结点时(从右孩子过来)进行输出(操作)。
2. 广度优先遍历
即层序遍历,按照从上到下,经过每一层。每一层又按照从左到右的顺序进行访问。
层序遍历:A B C D E F G H。
3. 深度遍历代码
//前序遍历
public void preorderTraversal(TreeNode root) {
if (root == null) {
return;
}
System.out.println(root.val);
preorderTraversal(root.lift);
postorderTraversal(root.right);
}
//中序遍历
public void inorderTraversal(TreeNode root) {
if (root == null) {
return;
}
inorderTraversal(root.lift);
System.out.println(root.val);
inorderTraversal(root.right);
}
//后序遍历
public void postorderTraversal(TreeNode root) {
if (root == null) {
return;
}
postorderTraversal(root.left);
postorderTraversal(root.right);
System.out.println(root.val);
}