一、前序遍历 - 递归
java">/* 1. 前序遍历 - 递归 */public void preOrder(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本意:打印树的根,左,右节点//2. 打印根节点的值System.out.print(root.val + " ");//3. 如果root.left也有左,右节点...,// 我们直接使用sout打印root.left.val...会造成打印不全。// 既然子树也是树,那么我们可以利用方法的递归去处理preOrder(root.left);preOrder(root.right);}
二、中序遍历 - 递归
java">/* 2. 中序遍历 - 递归 */public void inOrder(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本意:打印树的左,根,右节点//2. 如果root的左树也是一颗完整的树,// 此时直接打印root.left会造成打印不完全的现象// 既然如此,我们可以利用递归先打印root.left再打印当前树的根节点inOrder(root.left);//3. 打印根节点的值System.out.print(root.val + " ");//4. 打印root右树preOrder(root.right);}
三、后续遍历 - 递归
java">/* 3. 后续遍历 - 递归 */public void postOrder(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本意:打印树的左,右,根节点//2. 如果root的左树也是一颗完整的树,// 此时直接打印root.left会造成打印不完全的现象// 既然如此,我们可以利用递归先打印root.left再打印当前树的右树和根节点postOrder(root.left);postOrder(root.right);//3. 打印根节点的值System.out.print(root.val + " ");}
【小结】:
1. 之所以用到递归是由于root的左树,右树也是一颗完整的树,想要打印完整得先采用递归打印root的左树,右树,而不是直接用sout打印root.left,root.right。
2. 通过画图分析可知,当发现一个节点A的left节点为null时,会返回,使得代码回退到节点A的栈帧中,继续执行后面的打印节点A的right节点的代码。
四、其他方法
java">package bagone;import javax.management.relation.InvalidRoleInfoException;/*** Created with IntelliJ IDEA.* Description:* User: tangyuxiu* Date: 2024-08-26* Time: 18:43*/
public class MyBinaryTree {/* 使用内部类来表示树的节点 */private static class TreeNode {char val;TreeNode left;TreeNode right;public TreeNode(char val) {this.val = val;}}/* 1. 前序遍历 - 递归 */public void preOrder(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本意:打印树的根,左,右节点//2. 打印根节点的值System.out.print(root.val + " ");//3. 如果root.left也有左,右节点...,// 我们直接使用sout打印root.left.val...会造成打印不全。// 既然子树也是树,那么我们可以利用方法的递归去处理preOrder(root.left);preOrder(root.right);}/* 2. 中序遍历 - 递归 */public void inOrder(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本意:打印树的左,根,右节点//2. 如果root的左树也是一颗完整的树,// 此时直接打印root.left会造成打印不完全的现象// 既然如此,我们可以利用递归先打印root.left再打印当前树的根节点inOrder(root.left);//3. 打印根节点的值System.out.print(root.val + " ");//4. 打印root右树preOrder(root.right);}/* 3. 后续遍历 - 递归 */public void postOrder(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本意:打印树的左,右,根节点//2. 如果root的左树也是一颗完整的树,// 此时直接打印root.left会造成打印不完全的现象// 既然如此,我们可以利用递归先打印root.left再打印当前树的右树和根节点postOrder(root.left);postOrder(root.right);//3. 打印根节点的值System.out.print(root.val + " ");}/* 4. 树的节点个数 - 子问题思路 */public int size(TreeNode root) {//1. 如果根节点为nullif (root == null) {return 0;}//2. 根节点1 + 左树节点个数 + 右树节点数return 1 + size(root.left) + size(root.right);}/* 4. 树的节点个数 - 遍历思路 */public int sizeTreeNode;public void sizeTwo(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//本质:遍历树的根,左,右如果不为空sizeTreeNode的值就++//2. 根节点算一个所以++sizeTreeNode++;//3. root的左树,右树节点个数// 这里不可能直接下成判断不为null后sizeTreeNode的值就++// 因为root的左,右节点也是一颗树,下列代码中不接收返回值,// 或着说size方法的返回值为什么要定义成void是因为,我们已经定义了成员变量去记录成员个数了// 不用多此一举size(root.left);size(root.right);}/* 5. 获取叶子节点的个数 - 子问题思路 */public int getLeafNodeCount(TreeNode root) {//1. 如果根节点为nullif (root == null) {return 0;}//2. 如果根节点的左右子树都为nullif (root.left == null && root.right == null) {return 1;}//3. 收集左树,右树的叶子节点个数return getLeafNodeCount(root.left) + getLeafNodeCount(root.right);}/* 5. 获取叶子节点的个数 - 遍历思路 */public int sizeLeafNode;public void getLeafNodeCountTwo(TreeNode root) {//1. 如果根节点为nullif (root == null) {return;}//2. 如果根节点的左右子树都为nullif (root.left == null && root.right == null) {sizeLeafNode++;}//3. 收集左树,右树的叶子节点个数getLeafNodeCount(root.left);getLeafNodeCount(root.right);}/* 6. 获取第K层节点的个数 */public int getKLevelNodeCount(TreeNode root, int k) {//条件:所给的k一定是合法的//1. 如果根节点为null(递归的过程中也会出现root为null的情况)if (root == null) {return 0;}//2. k == 1if (k == 1) {return 1;}//3. 求root的左树,右树的第k-1层return getKLevelNodeCount(root.left, k - 1) + getKLevelNodeCount(root.right, k - 1);}/* 7. 获取二叉树的高度 */public int getHeight(TreeNode root) {//1. 如果根节点为nullif (root == null) {return 0;}// 核心:一棵树的高度等于,左树右树相比较的高度max + 1int hightOne = getHeight(root.left);int hightTwo = getHeight(root.right);return Math.max(hightOne,hightTwo) + 1;}/* 8. 检测值为value的元素是否存在 */public TreeNode find(TreeNode root, char val) {//1. 如果根节点为nullif (root == null) {return root;}//2. 判断根节点的值是否为valif (root.val == val) {return root;}//3. root的左树,右树,是否存在val值TreeNode valNode = find(root.left, val);if (valNode != null) {return valNode;}valNode = find(root.right, val);//4. 不管是否为null,直接返回valNode中的值即可return valNode;}
}