下面代码实现了二叉树的前中后序遍历,包括递归和非递归版本:
package tree;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
/**
* Created by International on 2018/4/26.
*/
public class BinaryTree {
public static void main(String[] args) {
TreeNode d = new TreeNode("D");
TreeNode e = new TreeNode("E");
TreeNode f = new TreeNode("F");
TreeNode b = new TreeNode("B", null, d);
TreeNode c = new TreeNode("C", e, f);
TreeNode a = new TreeNode("A", b, c);
List<TreeNode> result = new ArrayList<>();
/*
* 递归方法完成前、中、后序遍历
*/
// preTraverse(a, result);
// inTraverse(a, result);
// postTraverse(a, result);
/*
* 非递归方法完成前、中、后序遍历
*/
// preTraverse1(a, result);
// inTraverse1(a, result);
// postTraverse1(a, result);
printResult(result);
}
private static void printResult(List<TreeNode> result) {
for (int i = 0; i < result.size(); i++) {
if (i == 0) {
System.out.print(result.get(i).val);
} else {
System.out.print(" --> " + result.get(i).val);
}
}
}
public static void preTraverse(TreeNode node, List<TreeNode> result) {
if (node == null) {
return ;
}
// System.out.print(node.val);
result.add(node);
preTraverse(node.left, result);
preTraverse(node.right, result);
}
public static void inTraverse(TreeNode node, List<TreeNode> result) {
if (node == null) {
return ;
}
inTraverse(node.left, result);
// System.out.println(node.val);
result.add(node);
inTraverse(node.right, result);
}
public static void postTraverse(TreeNode node, List<TreeNode> result) {
if (node == null) {
return ;
}
postTraverse(node.left, result);
postTraverse(node.right, result);
result.add(node);
}
private static void preTraverse1(TreeNode node, List<TreeNode> result) {
if (node == null) {
return;
}
Deque<Guide> deque = new ArrayDeque<>();
deque.push(new Guide(0, node));
while (! deque.isEmpty()) {
Guide guide = deque.pop();
TreeNode treeNode = guide.node;
if (guide.opt == 0) {
if (treeNode.right != null) {
deque.push(new Guide(0, treeNode.right));
}
if (treeNode.left != null) {
deque.push(new Guide(0, treeNode.left));
}
deque.push(new Guide(1, treeNode));
} else if (guide.opt == 1) {
result.add(treeNode);
}
}
}
public static void inTraverse1(TreeNode node, List<TreeNode> result) {
if (node == null) {
return;
}
Deque<Guide> deque = new ArrayDeque<>();
deque.push(new Guide(0, node));
while (!deque.isEmpty()) {
Guide guide = deque.pop();
TreeNode treeNode = guide.node;
if (guide.opt == 0) {
if (treeNode.right != null) {
deque.push(new Guide(0, treeNode.right));
}
deque.push(new Guide(1, treeNode));
if (treeNode.left != null) {
deque.push(new Guide(0, treeNode.left));
}
} else if (guide.opt == 1) {
result.add(treeNode);
}
}
}
public static void postTraverse1(TreeNode node, List<TreeNode> result) {
if (node == null) {
return ;
}
Deque<Guide> deque = new ArrayDeque<>();
deque.push(new Guide(0, node));
while (!deque.isEmpty()) {
Guide guide = deque.pop();
TreeNode treeNode = guide.node;
if (guide.opt == 0) {
deque.push(new Guide(1, treeNode));
if (treeNode.right != null) {
deque.push(new Guide(0, treeNode.right));
}
if (treeNode.left != null) {
deque.push(new Guide(0, treeNode.left));
}
} else if (guide.opt == 1) {
result.add(treeNode);
}
}
}
}
class Guide {
int opt; // 0-visit; 1-print
TreeNode node;
public Guide(int opt, TreeNode node) {
this.opt = opt;
this.node = node;
}
}
class TreeNode {
String val;
TreeNode left;
TreeNode right;
public TreeNode(String val) {
this.val = val;
}
public TreeNode(String val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
package binaryTree;
import java.util.*;
/*
* 二叉树的递归与非递归版本,下面的版本中,非递归版本不如上面的清晰,上面版本通过构造一个任务类,将任务类压入、弹出栈完成遍历,不仅更清晰,也更简单。
*/
public class Traverse {
//递归版本
public static void preTraverse(TreeNode node) {
if(node == null)
return;
System.out.println(node.value);//或其他操作
preTraverse(node.left);
preTraverse(node.right);
}
public static void inTraverse(TreeNode node) {
if(node == null)
return;
inTraverse(node.left);
System.out.println(node.value);//或其他操作
inTraverse(node.right);
}
public static void postTraverse(TreeNode node) {
if(node == null)
return;
postTraverse(node.left);
postTraverse(node.right);
System.out.println(node.value);//或其他操作
}
//非递归版本
public static void rePreTraverse(TreeNode node) {
if(node == null)
return;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(node);
while(!stack.isEmpty()) {
TreeNode tmp = stack.pop();
System.out.println(tmp.value);//或其他操作
if(tmp.right != null)
stack.push(tmp.right);
if(tmp.left != null)
stack.push(tmp.left);
}
}
public static void reInTraverse(TreeNode node) {
if(node == null)
return;
Stack<TreeNode> stack = new Stack<TreeNode>();
while(node != null || !stack.isEmpty()) {
if(node != null) {
stack.push(node);
node = node.left;
} else {
node = stack.pop();
System.out.println(node.value);//或其他操作
node = node.right;
}
}
}
public static void rePostTraverse(TreeNode node) {
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode p = node;
//pre标记最近出栈的节点,用于判断是否是p节点的右孩子,如果是的话,就可以访问p节点
TreeNode pre = p;
//flag标记是出栈还是继续将左孩子进栈:true标记进栈;false标记出栈;
boolean flag = true;
while(p!=null || !s.isEmpty()) {
if(p!=null && flag) {
s.push(p);
p = p.left;
}
else {
if(s.isEmpty()) return;
p = s.peek();
if(p.right != null && p.right!=pre) {
p = p.right;
flag = true;
}
else {
p = s.pop();
System.out.println(p.value);
flag = false;
pre = p;
}
}
}
}
}