赞
踩
以上述中,前中后序遍历顺序如下:
前序遍历(中左右):5 4 1 2 6 7 8
中序遍历(左中右):1 4 2 5 7 6 8
后序遍历(左右中):1 2 4 7 8 6 5
在说二叉树的递归算法前,我们先了解下什么是递归算法
递归算法!既要有递去的过程,也需要有归来的过程。主要总结如下三步
1.确定终止条件:
2.确定终止条件时的递归函数的参数和返回值:
3.提取重复逻辑,化大为小
- 模型一: 在递去的过程中解决问题
- function recursion(大规模){
- if (end_condition){ // 明确的递归终止条件
- end; // 简单情景
- }else{ // 在将问题转换为子问题的每一步,解决该步中剩余部分的问题
- solve; // 递去
- recursion(小规模); // 递到最深处后,不断地归来
- }
- }
-
-
- 模型二: 在归来的过程中解决问题
- function recursion(大规模){
- if (end_condition){ // 明确的递归终止条件
- end; // 简单情景
- }else{ // 先将问题全部描述展开,再由尽头“返回”依次解决每步中剩余部分的问题
- recursion(小规模); // 递去
- solve; // 归来
- }
- }
- public static void preOrderRecur(TreeNode head) {
- if (head == null) {//2.确定
- return;//1.确定函数的返回值
- }
- //3.递归的真正处理逻辑
- //3.1 先中
- System.out.print(head.value + " ");
- //3.2 再左
- preOrderRecur(head.left);
- //3.2 再右
- preOrderRecur(head.right);
- }
- public static void preOrderRecur(TreeNode head) {
- if (head == null) {
- return;
- }
- preOrderRecur(head.left);
- System.out.print(head.value + " ");
- preOrderRecur(head.right);
- }
- public static void postOrderRecur(TreeNode head) {
- if (head == null) {
- return;
- }
- postOrderRecur(head.left);
- postOrderRecur(head.right);
- System.out.print(head.value + " ");
- }
问题的递归实现转换成非递归实现一般需要两步工作:
(1). 自己建立“堆栈(一些局部变量)”来保存这些内容以便代替系统栈,比如树的三种非递归遍历方式;
(2). 把对递归的调用转变为对循环处理。
思想:按照先处理中间节点、再使用栈的数据结构,按右节点、左节点入栈
步骤 | 操作 | 栈 |
1 | 打印节点5 | 节点6、节点4 |
2 | 打印节点4 | 节点6、节点2、节点1 |
3 | 打印节点1 | 节点6、节点2 |
4 | 打印节点2 | 节点6 |
5 | 打印节点6 | 节点8、节点7 |
6 | 打印节点7 | 节点8 |
7 | 打印节点8 | null |
- public static void preOrderIteration(TreeNode head) {
- if (head == null) {
- return;
- }
- Stack<TreeNode> stack = new Stack<>();
- stack.push(head);
- while (!stack.isEmpty()) {
- TreeNode node = stack.pop();
- System.out.print(node.value + " ");
- if (node.right != null) {
- stack.push(node.right);
- }
- if (node.left != null) {
- stack.push(node.left);
- }
- }
- }
题目:
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],3
/ \
9 20
/ \
15 7
返回:[3,9,20,15,7]
解题思路,层序遍历时需要一个容器,队列(先进先出)
步骤 | 操作 | 栈 |
1 | 打印节点3 | 节点9、节点20 |
2 | 打印节点9 | 节点20 |
3 | 打印节点20 | 节点15、节点7 |
4 | 打印节点15 | 节点7 |
5 | 打印节点7 | null |
代码思路
- /**
- * Definition for a binary tree node.
- * public class TreeNode {
- * int val;
- * TreeNode left;
- * TreeNode right;
- * TreeNode(int x) { val = x; }
- * }
- */
- class Solution {
- public int[] levelOrder(TreeNode root) {
- if(root == null) return new int[0];
- int[] res;
- List<Integer> list = new ArrayList<>();
- Queue<TreeNode> queue = new LinkedList<>();
- queue.add(root);
- while(!queue.isEmpty()){
- TreeNode node = queue.poll();
- list.add(node.val);//打印节点
- if(node.left != null)
- queue.add(node.left);//左子树入队
- if(node.right != null)
- queue.add(node.right);右子树入队
- }
- Integer[] arr = list.toArray(new Integer[list.size()]);
- res = new int[arr.length];
- for(int i = 0; i < arr.length; i ++)
- res[i] = arr[i];
- return res;
- }
- }
题目2:
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:输入:root = [1]
输出:[[1]]
示例 3:输入:root = []
输出:[]
- class Solution {
- public List<List<Integer>> levelOrder(TreeNode root) {
- List<List<Integer>> ret = new ArrayList<List<Integer>>();//定义外层
- if (root == null) {
- return ret;
- }
-
- Queue<TreeNode> queue = new LinkedList<TreeNode>();
- queue.offer(root);
- while (!queue.isEmpty()) {
- List<Integer> level = new ArrayList<Integer>();//定义内层
- int currentLevelSize = queue.size();
- for (int i = 1; i <= currentLevelSize; ++i) {
- TreeNode node = queue.poll();
- level.add(node.val);
- if (node.left != null) {
- queue.offer(node.left);
- }
- if (node.right != null) {
- queue.offer(node.right);
- }
- }
- ret.add(level);
- }
-
- return ret;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。