中序遍歷--遞迴和非遞迴(java版)
根據中序遍歷的順序,對於任一結點,優先訪問其左孩子,而左孩子結點又可以看做一根結點,然後繼續訪問其左孩子結點,直到遇到左孩子結點為空的結點才進行訪問,然後按相同的規則訪問其右子樹。因此其處理過程如下:
對於任一結點root,引入一個輔助節點p,其作用是:標記已經訪問過的節點,
1)將root壓入棧中,只有有左孩子,就壓入棧中
if(p!=null && p.left!=null) {
stk.add(p.left);
p = p.left;
}
2)對棧頂元素 q 進行出棧操作,訪問該棧頂結點。
如果 q 沒有右孩子,將輔助節點 p 設定為null。表示下一步還是進行2)操作,出棧操作
如果 q 有右孩子,將右孩子壓棧中,p = q的右孩子
p = stk.pop();//彈出棧頂節點 左孩子--->根節點
System.out.print(p.val+" ");//訪問
if(p!=null && p.right!=null) {//如果棧點元素有右孩子的話,將有節點壓入棧中
stk.add(p.right);
p = p.right;
}else
p = null;//p=stk.pop;已經訪問過p了,p設定為null
3)直到棧為空,遍歷結束。
程式碼重點是,2先訪問出棧,然後將5節點呀入棧中
import java.util.Stack; class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } public class Main { //中序遍歷 遞迴演算法 public static void InOrder(TreeNode root) { if(root==null)return; InOrder(root.left); System.out.print(root.val+" "); InOrder(root.right); } // 中序遍歷 非遞迴演算法 public static void InOrder2(TreeNode root) { if(root==null)return; Stack<TreeNode> stk = new Stack<TreeNode>(); TreeNode p = root;//輔助節點 stk.add(p); while(stk.isEmpty() == false) { //只要你有左孩子,就將左孩子壓入棧中 if(p!=null && p.left!=null) { stk.add(p.left); p = p.left; }else { p = stk.pop();//彈出棧頂節點 左孩子--->根節點 System.out.print(p.val+" ");//訪問 if(p!=null && p.right!=null) {//如果棧點元素有右孩子的話,將有節點壓入棧中 stk.add(p.right); p = p.right; }else p = null;//p=stk.pop;已經訪問過p了,p設定為null } } } public static void main(String[] args) { TreeNode root = new TreeNode(1); root.left = new TreeNode(2); root.right = new TreeNode(3); root.left.left = new TreeNode(4); root.left.right = new TreeNode(5); root.right.left = new TreeNode(6); root.right.right = new TreeNode(7); InOrder2(root); } }