1 二叉树三种遍历的递归、非递归实现
首先定义一棵二叉树的结构:
/**
* @Description 二叉树
* @Author lilong
* @Date 2019-02-27 10:23
*/
public class BinTreeNode {
private int data;
private BinTreeNode left;
private BinTreeNode right;
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BinTreeNode getLeft() {
return left;
}
public void setLeft(BinTreeNode left) {
this.left = left;
}
public BinTreeNode getRight() {
return right;
}
public void setRight(BinTreeNode right) {
this.right = right;
}
}
然后是3种遍历的递归、非递归实现:
import java.util.Stack;
/**
* @Description 前序遍历、中序遍历、后序遍历
* @Author lilong
* @Date 2019-02-27 11:26
*/
public class TraverseBinTree {
/* 递归 */
/**
* 前序遍历(递归)
* @param root
*/
public void preOrderRecursive(BinTreeNode root) {
if (root == null) {
return;
}
System.out.println(root.getData());
preOrderRecursive(root.getLeft());
preOrderRecursive(root.getRight());
}
/**
* 中序遍历(递归)
* @param root
*/
public void inOrderRecursive(BinTreeNode root) {
if (root == null) {
return;
}
preOrderRecursive(root.getLeft());
System.out.println(root.getData());
preOrderRecursive(root.getRight());
}
/**
* 后序遍历(递归)
* @param root
*/
public void postOrderRecursive(BinTreeNode root) {
if (root == null) {
return;
}
preOrderRecursive(root.getLeft());
preOrderRecursive(root.getRight());
System.out.println(root.getData());
}
/* 非递归 */
/**
* 前序遍历
* @param root
*/
public void preOrder(BinTreeNode root) {
if (root == null) {
return;
}
Stack<BinTreeNode> stack = new Stack<BinTreeNode>();
while (true) {
while (root != null) {
System.out.println(root.getData());
stack.push(root);
root = root.getLeft();
}
if (stack.isEmpty()) {
break;
}
root = stack.pop();
root = root.getRight();
}
}
/**
* 中序遍历
* @param root
*/
public void inOrder(BinTreeNode root) {
if (root == null) {
return;
}
Stack<BinTreeNode> stack = new Stack<BinTreeNode>();
while (true) {
while (root != null) {
stack.push(root);
root = root.getLeft();
}
if (stack.isEmpty()) {
break;
}
root = stack.pop();
System.out.println(root.getData());
root = root.getRight();
}
}
/**
* 后序遍历
* @param root
*/
public void postOrder(BinTreeNode root) {
if (root == null) {
return;
}
Stack<BinTreeNode> stack = new Stack<BinTreeNode>();
while (true) {
if (root != null) {
stack.push(root);
root = root.getLeft();
} else {
if (stack.isEmpty()) {
System.out.println("Stack is empty.");
return;
} else {
if (stack.peek().getRight() == null) {
root = stack.pop();
System.out.println(root.getData());
if (root == stack.peek().getRight()) {
System.out.println(stack.peek().getData());
stack.pop();
}
}
if (!stack.isEmpty()) {
root = stack.peek().getRight();
} else {
root = null;
}
}
}
}
}
}
最后测试下:
/**
* @Description 测试
* @Author lilong
* @Date 2019-02-27 11:35
*/
public class Test {
public static void main(String[] args) {
BinTreeNode node1 = new BinTreeNode();
node1.setData(2);
node1.setLeft(null);
node1.setRight(null);
BinTreeNode node2 = new BinTreeNode();
node2.setData(3);
node2.setLeft(null);
node2.setRight(null);
BinTreeNode root = new BinTreeNode();
root.setData(1);
root.setLeft(node1);
root.setRight(node2);
TraverseBinTree traverseBinTree = new TraverseBinTree();
// traverseBinTree.preOrderRecursive(root);
// traverseBinTree.inOrderRecursive(root);
// traverseBinTree.postOrderRecursive(root);
// traverseBinTree.preOrder(root);
// traverseBinTree.inOrder(root);
traverseBinTree.postOrder(root);
}
}
2.二叉树经典问题
根据前序遍历、中序遍历推出后序遍历。
前序:A B D E C F
中序:D B E A F C
前序遍历最左边的节点是根节点,此处是A,然后在中序遍历中找到A的位置,左边是左子树,右边是右子树。
以此类推,得到:
问:是否任意给定两种遍历方式就能得到另一种?
答:不是,这两种方式中必须有一种是中序遍历。
扩展:如果不是二叉树,而是一颗普通树,怎么遍历?