二叉樹的遞歸遍歷非常簡單,但是非遞歸遍歷就需要一點小技巧了,否則代碼邏輯容易混亂,這裏我給每一個節點定義里加入了一個訪問標記flag,這樣可以有效避免重複訪問和代碼邏輯不清楚的問題。
二叉樹中序非遞歸遍歷代碼如下:
package binarytree;
import java.util.Stack;
/**
* @author Gavenyeah
* @date Time: 2016年5月13日上午8:46:38
* @des:
*/
//非遞歸的中序遍歷二叉樹
public class InOrder{
public static void main(String args[]){
Node head = new InOrder().getTree();
new InOrder().inOrder(head);
}
public Node getTree(){
Node head = 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);
Node node8 = new Node(8);
head.left = node2;
head.right = node3;
node2.left = node4;
node2.right = node5;
node5.left = node7;
node4.right= node6;
node7.right= node8;
return head;
}
public void inOrder(Node head){
Stack<Node> stack = new Stack<Node>();//用堆棧來實現非遞歸的中序遍歷二叉樹
stack.push(head);
Node cur = null;
while(stack.size() > 0){
head = stack. peek();
while(head.left != null && head.left.flag == false){//有左子節點且未被訪問過
head = head.left;
stack.push(head);
}
//出棧並訪問節點
cur = stack.pop();
System.out.print(cur.data+" ");
cur.flag = true;
//進一步訪問右子節點
if(cur.right != null){
stack.push(cur.right);
head = cur.right;
}
}
}
}
先序非遞歸遍歷:
public void preOrder(Node head) {
Stack<Node> stack = new Stack<Node>();
stack.push(head);
while (stack.size() > 0) {
head = stack. peek();
if (head.flag == false) {
System.out.print(head.data + " ");
head.flag = true;
}
while (head.left != null && head.left.flag == false) {
head = head.left;
System.out.print(head.data + " ");
head.flag = true;
stack.push(head);
}
head = stack.pop();// 沒有左子樹或左子樹已被訪問的節點可以直接出棧
if (head.right != null && head.right.flag == false) {
head = head.right;
stack.push(head);
}
}
}
後序非遞歸遍歷:
public void postOrder(Node head){
Stack<Node> stack = new Stack<Node>();
stack.push(head);
while(stack.size() > 0){
head = stack.peek();
while(head.left != null && head.left.flag == false ||
head.right != null && head.right.flag == false){
if(head.right != null && head.right.flag == false){
stack.push(head.right);
}
if(head.left != null && head.left.flag == false){
stack.push(head.left);
}
head = stack.peek();
}
head = stack.pop();
System.out.print(head.data + " ");
head.flag = true;
}
}