二叉树的基础理论
递归法遍历二叉树
使用递归法遍历二叉树,首先要明确递归法的三个步骤
- 确定递归条件:也就是递归方法的参数和返回值。
- 确定递归方法的终止条件,一般作为方法的开头。if(xx == null){return;}
- 确定单层递归的逻辑。
二叉树前中后的递归遍历主要在于加入根结点的位置。
public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() {} TreeNode(int val) { this.val = val; } TreeNode(int val, TreeNode left, TreeNode right) { this.val = val; this.left = left; this.right = right; } } class Solution{ //递归函数 public void preorder(TreeNode node, List<Integer> list){ //终止条件 if (node == null){ return; } //前序遍历 list.add(node.val);//根 preorder(node.left, list); preorder(node.right,list); //中序遍历 preorder(node.left,list); list.add(node.val);//根 preorder(node.right,list); //后序遍历 preorder(node.left,list); preorder(node.right,list); list.add(node.val);//根 } }
迭代法遍历二叉树
迭代法用栈来实现元素的遍历,都是从root根节点开始遍历。因为栈是先进后出的数据结构,所以每种遍历方式要注意左右孩子进栈的顺序。while循环判断栈中是否没有元素了。
前序和后序遍历可以不借助指针cur,中序遍历需要借助cur指针来记录弹出的结点。
序遍历中访问节点(遍历节点)和处理节点(将元素放进result数组中)可以同步处理,但是中序就无法做到同步!
- 前序遍历
class Solution{ public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); if (root == null) { return result; } Stack<TreeNode> stack = new Stack<>(); stack.push(root);//根结点先入栈 while (!stack.isEmpty()) { TreeNode node = stack.pop();//先弹出根结点 result.add(node.val); if (node.right != null){ stack.push(node.right); } if (node.left != null) { stack.push(node.left); } } return result; } }
- 后序遍历
class Solution{ public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); if (root == null) { return result; } Stack<TreeNode> stack = new Stack<>(); stack.push(root);//根结点先入栈 while (!stack.isEmpty()) { TreeNode node = stack.pop();//先弹出根结点 result.add(node.val); if (node.left != null) { stack.push(node.left); } if (node.right != null){ stack.push(node.right); } } Collections.reverse(result); return result; } }
- 中序遍历
class Solution{ public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); if (root == null) { return result; } Stack<TreeNode> stack = new Stack<>(); TreeNode cur = root;//记录结点 while (cur != null || !stack.isEmpty()) { if (cur != null){ stack.push(cur); cur = cur.left; }else { //遍历到了叶子节点,就需要栈中弹出元素了 cur = stack.pop(); result.add(cur.val); cur = cur.right; } } return result; } }