1. 程式人生 > >leetcode-94-二叉樹的中序遍歷(binary tree inorder traversal)-java

leetcode-94-二叉樹的中序遍歷(binary tree inorder traversal)-java

題目及測試

package pid094;

import java.util.List;

/*中序遍歷二叉樹

給定一個二叉樹,返回它的中序 遍歷。

示例:

輸入: [1,null,2,3]
   1
    \
     2
    /
   3

輸出: [1,3,2]

進階: 遞迴演算法很簡單,你可以通過迭代演算法完成嗎?



}*/
public class main {
	
	public static void main(String[] args) {
		Integer[] x=new Integer[]{1,null,2,null,null,3,null};	
		BinaryTree tree=new BinaryTree(x);
		tree.printTree(tree.root);
		test(tree.root);
		
		
		
	}
		 
	private static void test(TreeNode ito) {
		Solution solution = new Solution();
		List<Integer> rtn;
		long begin = System.currentTimeMillis();
		rtn = solution.inorderTraversal(ito);//執行程式
		for(Integer num:rtn){
			System.out.println(num+" ");
		}

		System.out.println();
		System.out.println("-------------------");
	}

}

解法1(成功,2ms,較慢)

使用迴圈的方法,建立一個棧,將root放進去,每次取出棧的頭部now
當棧不為空時進行迴圈
如果now沒有左右子樹,說明遍歷已經到最深處,則把now的值加入list
如果有左右子樹,則首先把右子樹取出,放入棧頂,然後now。right=null,切斷now與右子樹的關係,不然待會會重複計算now的右子樹
然後放入now
最後方入左子樹,now。left=null

package pid094;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
	//先中序遍歷左子樹,再根,再右子樹
    public List<Integer> inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack=new Stack<>();
        List<Integer> result=new ArrayList<>();
        if(root==null){
        	return result;
        }
        stack.add(root);
        while(!stack.isEmpty()){
        	TreeNode now=stack.pop();
        	if(now.left==null&&now.right==null){
        		result.add(now.val);
        		continue;
        	}
        	if(now.right!=null){
        		stack.add(now.right);
        		now.right=null;
        	}
        	stack.add(now);
        	if(now.left!=null){
        		stack.add(now.left);
        		now.left=null;
        	}
        }       
    	return result;
    }
}

解法2(別人的)

同樣用棧,用迴圈,解法比我的高明

迴圈條件是curt不為null或者stack不為空
首先將curt自身及所有左子樹逐個加入stack
然後彈出stack頂部,將其加入result
最後curt為彈出的那個節點的右子樹
因為彈出的那個節點,左子樹要麼沒有,要麼已經被處理,所以只考慮右子樹
右子樹如果沒有,則下一次迴圈,直接curt = stack.pop();,相當於處理它的上層
如果有右子樹,那麼先處理該節點的右子樹,再處理上層

public class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: Inorder in ArrayList which contains node values.
     */
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        ArrayList<Integer> result = new ArrayList<Integer>();
        TreeNode curt = root;
        while (curt != null || !stack.empty()) {
            while (curt != null) {
                stack.add(curt);
                curt = curt.left;
            }
            curt = stack.pop();
            result.add(curt.val);
            curt = curt.right;
        }
        return result;
    }
}

解法3(別人的)

morris方法

空間o(1)

http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html

https://blog.csdn.net/workformywork/article/details/21628351