树节点定义:

class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}

递归建立二叉树:

    //递归建立二叉树
public static void BuildTree(TreeNode node, int data){
if(node == null){
node = new TreeNode(data);
} if(data <= node.val){
if(node.left == null){
node.left = new TreeNode(data);
}else{
BuildTree(node.left, data);
}
} if(data > node.val){
if(node.right == null){
node.right = new TreeNode(data);
}else{
BuildTree(node.right, data);
}
}
}

1、先序遍历

遍历方式:根节点-->左节点-->右节点

递归先序遍历:

    //先序递归遍历二叉树
public static List<Integer> preTravese(TreeNode root,List<Integer> arr){
if(root == null)
return arr;
if(root != null){
arr.add(root.val);
arr = preTravese(root.left,arr);
arr = preTravese(root.right,arr);
}
return arr;
}

非递归遍历:

对于任意一个结点p

1)访问结点p,并将p入栈

2)将p变为p的左孩子结点,如果p的不为空,循环至 1); 否则弹出当前栈顶使用p接收,将p变为p的右孩子结点;

3)当p结点为null并且栈为空时,结束循环。

代码:

    //非递归先序遍历
public static List<Integer> preorderTraversal(TreeNode root){
List<Integer> arr = new ArrayList<Integer>();
if(root == null){
return arr;
}
Stack<TreeNode> ts = new Stack<TreeNode>();
TreeNode ptr = root;
while( ptr != null || !ts.isEmpty()){
while(ptr != null){
arr.add(ptr.val);
ts.push(ptr);
ptr = ptr.left;
}
if( !ts.isEmpty()){
ptr = ts.pop();
ptr = ptr.right;
}
}
return arr;
}

2、中序遍历

遍历方式: 左子树-->根节点-->右子树

递归中序遍历:

    //中序递归遍历二叉树
public static List<Integer> inTravese(TreeNode root,List<Integer> arr){
if(root == null)
return arr;
if(root != null){
arr = inTravese(root.left,arr);
arr.add(root.val);
arr = inTravese(root.right,arr);
}
return arr;
}

非递归中序遍历:

对于任意一个结点p

1)当结点不为null,将结点压栈;

2)将p更新为它的左孩子,如果左孩子不为空,循环至 1);否则弹出栈顶元素赋值给p,访问p结点,p更新为p的右孩子;

3)当p为null 并且栈为空时结束循环。

代码:

    //中序非递归遍历
public static List<Integer> inorderTraversal(TreeNode root){
List<Integer> arr = new ArrayList<Integer>();
if(root == null){
return arr;
}
Stack<TreeNode> ts = new Stack<TreeNode>();
TreeNode ptr = root;
while( ptr != null || !ts.isEmpty() ){
while(ptr != null){
ts.push(ptr);
ptr = ptr.left;
}
if(!ts.isEmpty()){
ptr = ts.pop();
arr.add(ptr.val);
ptr = ptr.right;
}
}
return arr;
}

3、后序遍历

遍历方式:左子树-->右子树-->根节点

递归遍历:

    //后序递归遍历二叉树
public static List<Integer> lastTravese(TreeNode root,List<Integer> arr){
if(root == null)
return arr;
if(root != null){
arr = lastTravese(root.left,arr);
arr = lastTravese(root.right,arr);
arr.add(root.val);
}
return arr;
}

非递归遍历:

对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,但是此时不能将其出栈并访问,因为其右孩子还没有被访问。

接下来按照相同的规则对其右子树进行相同的处理,当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。

这样就可以保证正确的访问顺序。

可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。

代码:

首先新建一个类来记录结点是否是第一次弹栈:

//新建一个类,用来记录该结点是不是第一次弹栈
class NewTreeNode{
TreeNode ptr;
boolean isFirst;
public NewTreeNode(TreeNode ptr){
this.ptr = ptr;
this.isFirst = true;
}
}

非递归后序遍历二叉树:

    //后序非递归遍历二叉树
public static List<Integer> lastTraverse(TreeNode root){
List<Integer> arr = new ArrayList<Integer>();
if(root == null){
return arr;
}
Stack<NewTreeNode> nts = new Stack<NewTreeNode>();
NewTreeNode nptr = null;
TreeNode ptr = root;
while( ptr!= null || !nts.isEmpty()){
while(ptr != null){
nptr = new NewTreeNode(ptr);
nts.push(nptr);
ptr = ptr.left;
} if(!nts.isEmpty()){
nptr = nts.pop();
if(nptr.isFirst){
nptr.isFirst = false;
nts.push(nptr);
ptr = nptr.ptr.right;
}else{
arr.add(nptr.ptr.val);
//ptr置为null,因为此时它的左右子树都已经访问完毕
ptr = null;
}
}
}
return arr;
} }

二叉树的先序、中序以及后序遍历(递归 && 非递归)的更多相关文章

  1. 递归/非递归----python深度遍历二叉树(前序遍历,中序遍历,后序遍历)

    递归代码:递归实现很简单 '二叉树结点类' class TreeNode: def __init__(self, x): self.val = x self.left = None self.righ ...

  2. 二叉树的递归,非递归遍历(C++)

    二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的.对于二叉树,有前序.中序以及后序三种遍历方法.因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易 ...

  3. 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)

    一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...

  4. c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

    二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...

  5. C++二叉树前中后序遍历(递归&非递归)统一代码格式

    统一下二叉树的代码格式,递归和非递归都统一格式,方便记忆管理. 三种递归格式: 前序遍历: void PreOrder(TreeNode* root, vector<int>&pa ...

  6. 已知二叉树的中序序列为DBGEAFC,后序序列为DGEBFCA,给出相应的二叉树

    面对这种问题时我们该怎么解决? 今天写数据结构题.发现了一道总是碰见问题的题在这里我写了一种求解方法我自己称它为分层递归求解. 第一步通过观察我们知道后序遍历时最后一个是根节点A 在中序序列中A的左边 ...

  7. leetcode 236. 二叉树的最近公共祖先LCA(后序遍历,回溯)

    LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百 ...

  8. LeetCode 145 二叉树的后序遍历(非递归)

    题目: 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 解题思路: 1 ...

  9. 二叉树——遍历篇(递归/非递归,C++)

    二叉树--遍历篇 二叉树很多算法题都与其遍历相关,笔者经过大量学习.思考,整理总结写下二叉树的遍历篇,涵盖递归和非递归实现. 1.二叉树数据结构及访问函数 #include <stdio.h&g ...

随机推荐

  1. xml追加节点

    添加方法 public void XmlAppend(VisitM vm) { XmlDocument xmldoc = new XmlDocument(); string path = Server ...

  2. Python - 素数筛

    def shai(n): prim = list() check = list([1] * (n + 1)) for i in range(2, n + 1): if(check[i] == 1): ...

  3. Ngrok 内网穿透利器

    Ngrok是什么 Ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道.Ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放 为什么要使用Ngrok ...

  4. 如何在html中插入视频

    如何在html中插入视频 1,插入优酷视频: 在优酷分享界面有个html代码,直接复制放入body中,定义div的align居中即可 2.插入本地视频:用video属性  用mp4格式 <vid ...

  5. 面向对象之struct

    struct PointStruct { int pointx = 1; int pointy = 2; public PointStruct(int x, int y) { this.pointx ...

  6. BLE蓝牙通信指令交互过程配对与绑定

    最简单一次蓝牙通信需要以上相关步骤,包括discovery device,connect,pairing,bond等4个主要部分.BLE中主从机建立连接,到配对和绑定的过程如下图:

  7. java NIO ;mvn

    http://ifeve.com/java-nio-scattergather/ mvn introduction(install,conf, proxy,plugin,samples) http:/ ...

  8. java项目——数据结构实验报告

    java项目——数据结构总结报告 20135315  宋宸宁 实验要求 1.用java语言实现数据结构中的线性表.哈希表.树.图.队列.堆栈.排序查找算法的类. 2.设计集合框架,使用泛型实现各类. ...

  9. SQL 编辑

    局部变量: DECLARE @variable_name Datatype Variable_naem为局部变量的名称,Datatype为数据名称. 例如: DECLARE @name varchar ...

  10. 【Android测试】【随笔】在手机里用命令行创建中文文件夹

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4580319.html 不知道为啥当时自己写了一段在手机里用 ...