二叉树先序,中序,后序的非递归遍历(附java实现)
2017-04-23 11:35
357 查看
中序非递归遍历
自己走一遍就可以理解,但是总是记不住
先序非递归遍历
对比先序和中序的非递归遍历,差别只是在visit(p)函数的调用位置,遍历规则大同小异,:
均是先走到二叉树的最左,先序需要边走边visit。pop栈只是要走右子树;中序需要保证左树遍历完,才可以pop栈访问,再走右子树;
后序非递归遍历
后续非递归时,一个根节点能够被访问的前提是:无右子树或右子树已被访问过。所以以右子树为条件,在元素出栈后,访问元素前,需要判断lastVisit是否是该节点的右子树,若是,则执行访问;若不是说明没有访问该节点的右子树,此节点目前不能访问,因此将其再次入栈,继续此节点的右子树循环
java实现的三种遍历
参考:
三种遍历方法详细介绍
http://blog.csdn.net/zhangxiangdavaid/article/details/37115355
自己走一遍就可以理解,但是总是记不住
//边界条件判断 if(root==null) return; Stack stack=null; p=root;//这样设置,而非将root入栈,可以代表每个完整树的开始 while(p非空||stack非空){ //沿着p的左指针非空进栈走到最左,最左边可能有两种情况,最左子树无左右子树和最左子树只有右子树 while(p非空){ stack.push(p); p=p.lchild; } //我理解此时,栈必不为空;所以无需判断栈空 stack.pop(p); visit(p);//出栈visit; p=p.rchild;//再从p的右子树循环走到最左 }
先序非递归遍历
if(root==null) return; Stack stack=null; p=root;//循环时与初始条件无关,易于接下来的分析 while(p非空||stack非空){ //沿着p的左指针非空进栈走到最左 while(p非空){ stack.push(p); visit(p);//先序遍历,先访问结点,存入栈中是为了查找右子树 p=p.lchild; } //同理,栈必不为空;所以直接弹出 stack.pop(p); p=p.rchild;//右子树无论空或非空直接下一个while就行 }
对比先序和中序的非递归遍历,差别只是在visit(p)函数的调用位置,遍历规则大同小异,:
均是先走到二叉树的最左,先序需要边走边visit。pop栈只是要走右子树;中序需要保证左树遍历完,才可以pop栈访问,再走右子树;
后序非递归遍历
后续非递归时,一个根节点能够被访问的前提是:无右子树或右子树已被访问过。所以以右子树为条件,在元素出栈后,访问元素前,需要判断lastVisit是否是该节点的右子树,若是,则执行访问;若不是说明没有访问该节点的右子树,此节点目前不能访问,因此将其再次入栈,继续此节点的右子树循环
//边界条件判断 if(root==null) return; Stack stack = null; lastVisit = null;//记录上次访问的结点 p = root; while(p非空||stack非空){ //后序遍历也需走到最左 while(p非空){ stack.push(p); p=p.lchild; } //栈必不为空,直接弹出 stack.pop(p); //如果此节点的右子树为空,或者上次访问的结点 是此节点的右子树,则表明 现在! 可以访问 此节点! if(p.rchild == null || lastVisit == p.rchild){ visit(p); lastVisit=p; p=null;//此处必须设null,否则循环 } else{ stack.push(p);//对于刚才的出栈,现已知是错误的选择,所以再入栈 p=p.rchild;//再从p的右子树开始新的循环 } }
java实现的三种遍历
import java.util.ArrayDeque; import java.util.Deque; class Node { int item; Node left; Node right; Node(Node left, int element, Node right) { this.item = element; this.left = left; this.right = right; } } public class Travesal { public static void preOrder(Node root) { Node p = root; Deque<Node> stack = new ArrayDeque<Node>(); if (p != null) { while (!stack.isEmpty() || p != null) { while (p != null) { System.out.println(p.item); stack.offerFirst(p);// offerFirst prefer stack.addFirst(p); p = p.left; } p = stack.pollFirst();// pollLast prefer removeLast(); p = p.right; } } } public static void inOrder(Node root) { Node p = root; Deque<Node> stack = new ArrayDeque<Node>(); if (p != null) { while (!stack.isEmpty() || p != null) { while (p != null) { stack.offerFirst(p);// offerFirst prefer stack.addFirst(p); p = p.left; } p = stack.pollFirst();// pollLast prefer removeLast(); System.out.println(p.item); p = p.right; } } } public static void postOrder(Node root) { Node p = root; Node lastVisit=null; Deque<Node> stack = new ArrayDeque<Node>();//基于循环队列的双端队列 if (p != null) { while (!stack.isEmpty() || p != null) { while (p != null) { stack.offerFirst(p);// offerFirst prefer than stack.addFirst(p); p = p.left; } p = stack.pollFirst();// pollLast prefer than removeLast(); if(lastVisit==p.right||p.right==null){ System.out.println(p.item); lastVisit=p; p=null;//一定要置空,否则死循环 }else{ stack.offerFirst(p);//对于刚才的出栈,现已知是错误的选择,所以再入栈 p = p.right; } } } } public static void main(String[] args) { Node node9 = new Node(null, 9, null); Node node7 = new Node(node9, 7, null); Node node12 = new Node(null, 12, null); Node node13 = new Node(null, 13, null); Node node8 = new Node(node12, 8, node13); Node node3 = new Node(node7, 3, node8); Node node4 = new Node(null, 4, null); Node node1 = new Node(node3, 1, node4); //preOrder(node1);inOrder(node1); postOrder(node1); } }
参考:
三种遍历方法详细介绍
http://blog.csdn.net/zhangxiangdavaid/article/details/37115355
相关文章推荐
- Java实现对二叉树前序/中序/后序的递归与非递归算法
- java实现二叉树的添加和中序,前序排列;求二叉树的高度
- Java迭代实现二叉树的前序、中序、后序遍历
- 二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现
- 通过前序遍历和中序遍历重建二叉树以及输出后序遍历(Java实现)
- java实现二叉树的先序、中序、后序遍历
- java实现二叉树的先序、中序和后序迭代器
- 二叉树高度,栈实现二叉树的先序,中序,后序遍历的非递归遍历,二叉树层次遍历
- java实现树的前序,后序,中序的非递归遍历
- 一直二叉树的前序遍历和中序遍历的结果,重建该二叉树 Java代码实现
- java实现二叉树的先序、中序、后序遍历
- 利用通用栈实现对于二叉树的前序、中序、后序的非递归遍历
- 用java实现二叉树非递归的前序,中序,后序遍历算法
- 根据前序遍历和中序遍历重建二叉树的Java实现
- 二叉树的先序、中序和后序的非递归遍历(C语言实现)
- java实现二叉树的非递归遍历
- C++实现二叉树的递归遍历与非递归遍历(先序、中序、后序、层序)
- Java实现二叉树的创建、递归/非递归遍历
- 通过前序遍历和中序遍历重建二叉树以及输出后序遍历(Java实现)(二)
- 二叉树基本操作的递归实现(二叉树建立,先序,中序,后序,深度的递归遍历。广度优先,高度优先的非递归遍历)