Java实现对二叉树前序/中序/后序的递归与非递归算法
二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
实例化遍历类并调用各个遍历方法。
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
首先创建节点类,并在里面添加了一个创建树的方法,调用后就可以返回一个包含7个节点的二叉树。
点击(此处)折叠或打开
-
public class Node {
-
// 节点值
-
public int value;
-
-
// 左子节点
-
public Node left;
-
-
// 右子节点
-
public Node right;
-
-
Node(int va) {
-
value = va;
-
}
-
-
Node(int va, Node le, Node ri) {
-
value = va;
-
left = le;
-
ri = right;
-
}
-
-
/**
-
* 创建一颗二叉树
-
*
-
* @return 根节点
-
*/
-
public static Node createTree() {
-
Node root = new Node(0);
-
Node node1 = new Node(1);
-
Node node2 = new Node(2);
-
Node node3 = new Node(3);
-
Node node4 = new Node(4);
-
Node node5 = new Node(5);
-
Node node6 = new Node(6);
-
Node node7 = new Node(7);
-
-
root.left = node1;
-
root.right = node2;
-
node1.left = node3;
-
node1.right = node4;
-
node2.left = node5;
-
node2.right = node6;
-
node3.left = node7;
-
return root;
-
}
- }
创建遍历类,在该类里实现各种遍历方法。
点击(此处)折叠或打开
-
import java.util.ArrayList;
-
-
public class Traverse {
-
-
/**
-
* 递归前序遍历
-
*
-
* @param root
-
*/
-
public void recursiveProOrder(Node root) {
-
// 遍历根节点
-
if (root != null) {
-
System.out.print(root.value);
-
}
-
// 遍历左子树
-
if (root.left != null) {
-
recursiveProOrder(root.left);
-
}
-
// 遍历右子树
-
if (root.right != null) {
-
recursiveProOrder(root.right);
-
}
-
}
-
-
/**
-
* 前序遍历
-
*
-
* @param root
-
*/
-
public void proOrder(Node root) {
-
// 使用ArrayList作为堆栈
-
ArrayList<Node> stack = new ArrayList<Node>();
-
// 栈指针
-
int top = -1;
-
Node current = root;
-
while (true) {
-
if (current != null) {
-
System.out.print(current.value);
-
}
-
// 右子节点进栈
-
if (current.right != null) {
-
stack.add(current.right);
-
top++;
-
}
-
// 左子节点进栈
-
if (current.left != null) {
-
stack.add(current.left);
-
top++;
-
}
-
// 如果栈内还有节点,栈顶节点出栈
-
if (top > -1) {
-
current = stack.get(top);
-
stack.remove(top--);
-
} else {
-
break;
-
}
-
}
-
}
-
-
/**
-
* 递归中序遍历
-
*
-
* @param root
-
*/
-
public void recursiveInOrder(Node root) {
-
if (root != null) {
-
if (root.left != null) {
-
recursiveInOrder(root.left);
-
}
-
System.out.print(root.value);
-
if (root.right != null) {
-
recursiveInOrder(root.right);
-
}
-
}
-
}
-
-
/**
-
* 中序遍历
-
*
-
* @param root
-
*/
-
public void inOrder(Node root) {
-
if (root != null) {
-
ArrayList<Node> stack = new ArrayList<Node>();
-
int top = -1;
-
Node current = root;
-
while (current != null || top > -1) {
-
if (current != null) {
-
// 一直深入地寻找左子节点,并将路上的节点都进栈
-
stack.add(current);
-
top++;
-
current = current.left;
-
} else {
-
// 取出栈顶节点,并继续遍历右子树
-
current = stack.get(top);
-
stack.remove(top--);
-
System.out.print(current.value);
-
current = current.right;
-
}
-
}
-
}
-
}
-
-
/**
-
* 递归后续遍历
-
*
-
* @param root
-
*/
-
public void recursivePostOrder(Node root) {
-
if (root != null) {
-
if (root.left != null) {
-
recursivePostOrder(root.left);
-
}
-
if (root.right != null) {
-
recursivePostOrder(root.right);
-
}
-
System.out.print(root.value);
-
}
-
}
-
-
/**
-
* 后序遍历:可以被遍历的节点都要进栈出栈两次,所以添加第二个栈用来标示进栈次数
-
*
-
* @param root
-
*/
-
public void postOrder(Node root) {
-
if (root != null) {
-
// 用来保存节点的栈
-
ArrayList<Node> stack = new ArrayList<Node>();
-
// 用来保存标志位的栈
-
ArrayList<Integer> stack2 = new ArrayList<Integer>();
-
// 两个栈共用的栈指针
-
int top = -1;
-
int tag;
-
Node current = root;
-
do {
-
//将所有左子节点进栈
-
while (current != null) {
-
stack.add(current);
-
stack2.add(0);
-
top++;
-
current = current.left;
-
}
-
//取出栈顶节点,并判断其标志位
-
current = stack.get(top);
-
tag = stack2.get(top);
-
stack2.remove(top);
-
if (tag == 0) {
-
// tag为0,表明该节点第一次进栈,还需要进栈一次,同时修改标志位
-
current = current.right;
-
stack2.add(1);
-
} else {
-
// tag不位0,表明非首次进栈,可以遍历了。
-
stack.remove(top);
-
top--;
-
System.out.print(current.value);
-
current = null;
-
}
-
} while (current != null || top != -1);
-
}
-
}
- }
点击(此处)折叠或打开
-
public class Algorithm {
-
-
public static void main(String[] args) {
-
-
Node root=Node.createTree();
-
System.out.print("前序遍历:
");
-
new Traverse().proOrder(root);
-
System.out.println();
-
System.out.print("前序递归遍历:
");
-
new Traverse().recursiveProOrder(root);
-
System.out.println();
-
System.out.print("中序遍历:
");
-
new Traverse().inOrder(root);
-
System.out.println();
-
System.out.print("中序递归遍历:
");
-
new Traverse().recursiveInOrder(root);
-
System.out.println();
-
System.out.print("后序遍历:
");
-
new Traverse().postOrder(root);
-
System.out.println();
-
System.out.print("后序递归遍历:
");
- new Traverse().recursivePostOrder(root);
- }
输出结果:
前序遍历: 01374256
前序递归遍历: 01374256
中序遍历: 73140526
中序递归遍历: 73140526
后序遍历: 73415620
后序递归遍历: 73415620
如果你喜欢本文, 请长按二维码,关注公众号 分布式编程.
作者:分布式编程
出处:https://zthinker.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。