思想:前序(根左右),中序(左根右),后序(左右根)

前序非递归遍历:

首先判断根是否为空,将根节点入栈

1.若栈为空,则退出循环
2.将栈顶元素弹出,访问弹出的节点
3.若弹出的节点的右孩子不为空则将右孩子入栈
4.若弹出的节点的左孩子不为空则将左孩子入栈
5.返回1

后序遍历非递归:

前序:根->左->右
后序:左->右->根

可以把后序当作:根->右->左,然后再反转一下即可

中序遍历非递归:

根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。因此其处理过程如下:

对于任一结点P,

1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;

2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;

3)直到P为NULL并且栈为空则遍历结束。

树结构

/**
* Copyright(C) 2019 Hangzhou Differsoft Co., Ltd. All rights reserved.
*
*/
package com.java.offer.tree; /**
* @since 2019年2月15日 上午9:23:17
* @author xuchao
*
* 树节点
*/
public class TreeNode<T> { public T val;
public TreeNode<T> left;
public TreeNode<T> right; public TreeNode(T val) {
this.val = val;
this.left = null;
this.right = null;
}
}

程序:

/**
* Copyright(C) 2019 Hangzhou Differsoft Co., Ltd. All rights reserved.
*
*/
package com.java.offer.tree; import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack; /**
* @since 2019年2月15日 上午9:28:07
* @author xuchao
*
* 二叉树的遍历:
* 前序(根左右),中序(左根右),后序(左右根),层序
*/
public class TraversalOfBinaryTree { // 前序递归
public static List<Integer> preorderRecursively(TreeNode<Integer> node){
List<Integer> list = new ArrayList<>();
if (node == null) {
return list;
}
list.add(node.val);
list.addAll(preorderRecursively(node.left));
list.addAll(preorderRecursively(node.right));
return list;
}
// 中序递归
public static List<Integer> inorderRecursively(TreeNode<Integer> node){
List<Integer> list = new ArrayList<>();
if (node == null) {
return list;
}
list.addAll(inorderRecursively(node.left));
list.add(node.val);
list.addAll(inorderRecursively(node.right));
return list;
} // 后序递归
public static List<Integer> postorderRecursively(TreeNode<Integer> node){
List<Integer> list = new ArrayList<>();
if (node == null) {
return list;
}
list.addAll(postorderRecursively(node.left));
list.addAll(postorderRecursively(node.right));
list.add(node.val);
return list;
} // 前序非递归
public static List<Integer> preorderIteratively(TreeNode<Integer> node) {
Stack<TreeNode<Integer>> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
if (node == null) {
return list;
}
stack.push(node);
while (!stack.isEmpty()) {
node = stack.pop();
list.add(node.val);
if(node.right!=null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
return list;
} // 中序非递归
public static List<Integer> inorderIteratively(TreeNode<Integer> node) {
Stack<TreeNode<Integer>> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
TreeNode<Integer> cur = node;
if (node == null) {
return list;
}
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
}else {
cur = stack.pop();
list.add(cur.val);
cur = cur.right;
}
}
return list;
} // 后序非递归
public static List<Integer> postorderIteratively(TreeNode<Integer> node) {
Stack<TreeNode<Integer>> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
if (node == null) {
return list;
}
stack.push(node);
while(!stack.isEmpty()) {
node = stack.pop();
list.add(node.val);
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
Collections.reverse(list);
return list;
} // 层次遍历
public static List<Integer> levelorder(TreeNode<Integer> node) {
Queue<TreeNode<Integer>> queue = new LinkedList<>();
List<Integer> list = new ArrayList<>();
if (node == null) {
return list;
}
queue.add(node);
while (!queue.isEmpty()) {
node = queue.remove();
list.add(node.val);
if (node.left != null) {
queue.add(node.left);
}
if(node.right!=null) {
queue.add(node.right);
}
}
return list;
} // 1
// 2 3
// 4 5 // pre:1-2-4-3-5 in:2-4-1-5-3 post:4-2-5-3-1 level:1-2-3-4-5
public static void main(String[] args) {
TreeNode<Integer> node = new TreeNode<Integer>(1);
node.left = new TreeNode<Integer>(2);
node.right = new TreeNode<Integer>(3);
node.left.right = new TreeNode<Integer>(4);
node.right.left = new TreeNode<Integer>(5); // 前中后遍历递归
System.out.println(preorderRecursively(node).toString());
System.out.println(inorderRecursively(node).toString());
System.out.println(postorderRecursively(node).toString()); System.out.println("");
// 前中后遍历非递归
System.out.println(preorderIteratively(node).toString());
System.out.println(inorderIteratively(node).toString());
System.out.println(postorderIteratively(node).toString()); // 层次遍历
System.out.println(levelorder(node).toString());
}
}

剑指offer第二版-总结:二叉树的遍历的更多相关文章

  1. 剑指offer第二版-8.二叉树的下一个节点

    描述:给定一棵二叉树和其中的一个节点,找出中序遍历序列的下一个节点.树中应定义指向左节点.右节点.父节点的三个变量. 思路: 1.如果输入的当前节点有右孩子,则它的下一个节点即为该右孩子为根节点的子树 ...

  2. 《剑指offer(第二版)》面试题55——判断是否为平衡二叉树

    一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点 ...

  3. 《剑指offer 第二版》题解

    剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试 ...

  4. 经典面试题目——找到第n个丑数(参考《剑指offer(第二版)》面试题49)

    一.题目大意 给你一个数n,要求返回第n个丑数.其中,丑数的定义如下: 丑数是指只包含因子2.3和5的数.(数字1也是丑数,不过是个特例)引用<剑指offer>上的话来说,对于一个数M,如 ...

  5. 《剑指offer(第二版)》——面试题36:二叉搜索树与双向链表

    具体的题目大意和参考思路在此处不详述(见<剑指offer>),实质就是在中序遍历的过程中调整指针的指向,关于中序遍历有递归和非递归两种操作,所以此处也用了两种方法. 方法1(递归法): 代 ...

  6. 《剑指offer(第二版)》面试题60——n个骰子的点数

    一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释 ...

  7. 《剑指offer(第二版)》面试题64——求1+2+...+n

    一.题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句 (即三元运算符,A? B : C) 二.题解 虽然求和问 ...

  8. 结合《剑指offer(第二版)》面试题51来谈谈归并排序

    一.题目大意 给定一个数组A,对于数组A中的两个数字,如果排在前面的一个数字大于(必须大于,等于不算)后面的数字,则这两个数字组成一个逆序对.要求输出数组A中的逆序对的总数.例如,对于数组{7,5,6 ...

  9. 剑指offer第二版-7.重建二叉树

    描述:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树.假设前序遍历或中序遍历的结果中无重复的数字. 思路:前序遍历的第一个元素为根节点的值,据此将中序遍历数组拆分为左子树+root+右子树,前序遍 ...

随机推荐

  1. Android项目实战(一): SpannableString与SpannableStringBuilder

    原文:Android项目实战(一): SpannableString与SpannableStringBuilder 前言: 曾经在一些APP中的一些类似“帮助”“关于”的界面看过一行文字显示不同的颜色 ...

  2. CPU和GPU双低效,摩尔定律之后一万倍 ——写于TPU版AlphaGo重出江湖之际

    本文来自计算机体系结构专家王逵.他认为,“摩尔定律结束之后,性能提升一万倍”不会是科幻,而是发生在我们眼前的事实.   2008年,<三体2:黑暗森林>里写到:   真的很难,你冬眠后不久 ...

  3. UWP入门(八)--几个简单的控件

    原文:UWP入门(八)--几个简单的控件 每天看几个,要不聊几天我就可以看完啦,加油! 看效果 1. CheckBox <TextBlock Grid.Row="0" Tex ...

  4. ECSHOP 数据库结构说明

    ECSHOP 数据库结构说明 (适用版本v2.7.3) 1.account_log 用户账目日志表 字段 类型 Null/默认 注释 log_id mediumint(8) 否 / 自增 ID 号 u ...

  5. Raknet是一个基于UDP网络传输协议的C++网络库(还有一些其它库,比如nanomsg,fastsocket等等)

    Raknet是一个基于UDP网络传输协议的C++网络库,允许程序员在他们自己的程序中实现高效的网络传输服务.通常情况下用于游戏,但也可以用于其它项目. Raknet有以下好处: 高性能 在同一台计算机 ...

  6. MSYS2 环境搭建,并整合Qt

    本机环境:Windows XP 32位MSYS2地址:http://sourceforge.net/projects/msys2/ 下载32位版本,地址:http://sourceforge.net/ ...

  7. Delphi中无边框窗体应用程序使任务栏右键菜单有效的方法

    最近在Delphi开发中用到了无边框窗体显示时,无法在任务栏使用右键弹出菜单的情况,经过整理,通过以下方法可以使右键菜单出现: procedure Tfrm_Base.InitSysMenu;var  ...

  8. 知识的内化:学习、实践、输出(与Focus Feedback FixIt的原理是一致的)

    一个人的能力分三个层次: 资源,比如知识.技能.经验.时间.精力.金钱.人脉等 应用流程,即使用资源解决问题的能力,包括做事的方法.流程.策略等,它是你整合应用资源创造价值的能力. 价值取向,即你觉得 ...

  9. Java的Qt绑定 jambi

    大二在学java,所以有时会写点java的小程序,可是习惯了qt的界面,使用AWT和swing让我有些不适,后来发现了jambi,才知道原来早就有了java的绑定版,所以迫不及待的安装了上.      ...

  10. Tido 习题-二叉树-树状数组实现

    题目描述 这就是一个简单的树状数组入门题 可以动态地进行区间和查询 随时可能会进行更新   #include<iostream> #include<cstdio> #inclu ...