二叉树的三种遍历是经常用到的基本操作。递归的写法相对简单,但有时候非递归的实现,却需要想一想。今天,统一思考了一下,并用Java进行了实现,记录在这里,以便脑子宕机的时候看看。
一切的递归,都可以用自己写的栈来实现。
二叉树节点类:
/**
* 二叉树节点
*/
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val = val;
}
}```
具体的算法实现类:
```java
import java.util.*;
/**
* 二叉树的前序、中序、后序遍历的实现
*/
public class Order {
public static void main(String[] args) {
TreeNode[] tree = new TreeNode[7];
for(int i=0; i<7; i++){
tree[i] = new TreeNode(i);
}
tree[0].left = tree[1];
tree[0].right = tree[2];
tree[1].left = tree[3];
tree[1].right = tree[4];
tree[2].left = tree[5];
tree[2].right = tree[6];
Order order = new Order();
System.out.println("前序遍历递归版:");
order.printList(order.preOrder(tree[0]));
System.out.println("前序遍历非递归版:");
order.printList(order.preOrderLoop(tree[0]));
System.out.println("中序遍历递归版:");
order.printList(order.midOrder(tree[0]));
System.out.println("中序遍历非递归版:");
order.printList(order.midOrderLoop(tree[0]));
System.out.println("后序遍历递归版:");
order.printList(order.backOrder(tree[0]));
System.out.println("后序遍历非递归版:");
order.printList(order.backOrderLoop(tree[0]));
}
public void printList(LinkedList<Integer> list){
Iterator<Integer> iter = list.iterator();
while(iter.hasNext()){
System.out.print(iter.next()+" ");
}
System.out.println();
}
/**
* 用递归方式实现前序遍历
* @param root
* @return
*/
public LinkedList<Integer> preOrder(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
if(root==null){
return list;
}
list.add(root.val);
list.addAll(preOrder(root.left));
list.addAll(preOrder(root.right));
return list;
}
/**
* 前序遍历的栈实现
* @param root
* @return
*/
public LinkedList<Integer> preOrderLoop(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
if(root!=null){
stack.push(root);
}
while(!stack.isEmpty()){
TreeNode current = stack.pop();
list.add(current.val);
if(current.right!=null){
stack.push(current.right);
}
if(current.left!=null){
stack.push(current.left);
}
}
return list;
}
/**
* 递归方式实现中序遍历
* @param root
* @return
*/
public LinkedList<Integer> midOrder(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
if(root==null){
return list;
}
list.addAll(midOrder(root.left));
list.add(root.val);
list.addAll(midOrder(root.right));
return list;
}
/**
* 用栈实现中序遍历
* @param root
* @return
*/
public LinkedList<Integer> midOrderLoop(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode current = root;
while(current!=null){
stack.push(current);
current = current.left;
}
while(!stack.isEmpty()){
TreeNode temp = stack.pop();
list.add(temp.val);
TreeNode node = temp.right;
while(node!=null){
stack.push(node);
node = node.left;
}
}
return list;
}
/**
* 递归方式实现后序遍历
* @param root
* @return
*/
public LinkedList<Integer> backOrder(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
if(root==null){
return list;
}
list.addAll(backOrder(root.left));
list.addAll(backOrder(root.right));
list.add(root.val);
return list;
}
/**
* 后序遍历的栈实现
* @param root
* @return
*/
public LinkedList<Integer> backOrderLoop(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
if(root!=null){
stack.push(root);
}
while(!stack.isEmpty()){
TreeNode temp = stack.pop();
list.addFirst(temp.val);
if(temp.left!=null){
stack.push(temp.left);
}
if(temp.right!=null){
stack.push(temp.right);
}
}
return list;
}
}
测试用例的运行结果如下:
前序遍历递归版:
0 1 3 4 2 5 6
前序遍历非递归版:
0 1 3 4 2 5 6
中序遍历递归版:
3 1 4 0 5 2 6
中序遍历非递归版:
3 1 4 0 5 2 6
后序遍历递归版:
3 4 1 5 6 2 0
后序遍历非递归版:
3 4 1 5 6 2 0