1. 程式人生 > >二叉樹先序中序後序遍歷實現

二叉樹先序中序後序遍歷實現

一、遞迴實現

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class TreeToSequence {
    public int[][] convert(TreeNode root) {
        // write code here
        //函式返回值是一個二維陣列,此二維陣列儲存了三種遍歷方式的遍歷結果
        //首先建立三個list結構用來儲存遍歷出的樹型結構
        List<Integer> preorderList = new ArrayList<Integer>();
        List<Integer> inorderList = new ArrayList<Integer>();
        List<Integer> postorderList = new ArrayList<Integer>();
        
        //呼叫遍歷函式
        transPreorder(root, preorderList);
        transInorder(root, inorderList);
        transPostorder(root, postorderList);
        //建立二維陣列
        int length = preorderList.size();
        int[][] result = new int[3][length];
        
        //取出遍歷結果
        for(int i = 0; i < length; i++) {
            result[0][i] = preorderList.get(i);
        }
 
        for(int i = 0; i < length; i++) {
            result[1][i] = inorderList.get(i);
        }
 
        for(int i = 0; i < length; i++) {
            result[2][i] = postorderList.get(i);
        }
 
        return result;
    }
    //先序遍歷
    public void transPreorder(TreeNode node, List<Integer> list){
        if(node==null){
            return;
        }
        list.add(node.val);
        transPreorder(node.left,list);
        transPreorder(node.right,list);
        
    }
    //中序遍歷
    public void transInorder(TreeNode node, List<Integer> list){
        if(node==null){
            return;
        }
        transInorder(node.left,list);
        list.add(node.val);
        transInorder(node.right,list);
    }
    //後序遍歷
    public void transPostorder(TreeNode node, List<Integer> list){
        if(node==null){
            return;
        }
        transPostorder(node.left,list);
        transPostorder(node.right,list);
        list.add(node.val);
    }
}

二、非遞迴實現

import java.util.*;

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}*/
public class TreeToSequence {
    public int[][] convert(TreeNode root) {
        // write code here
        List<Integer> pre = new ArrayList<Integer>();
        List<Integer> in = new ArrayList<Integer>();
        List<Integer> post = new ArrayList<Integer>();
        preOrder(root, pre);
        inOrder(root, in);
        postOrder(root, post);
        int[][] res = new int[3][pre.size()];
        for(int i = 0; i < pre.size(); i++){
            res[0][i] = pre.get(i);
            res[1][i] = in.get(i);
            res[2][i] = post.get(i);
        }
        return res;
    }
    
    //先序遍歷
    public void preOrder(TreeNode root,List<Integer> list){
        if(root == null)
            return;
        //建立一個棧結構,並將根節點入棧
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        //當棧不為空時,彈出棧頂元素並記錄,如果該元素的右子樹不為空,那麼將他的右子樹入棧,繼續,如果他的左子樹不為空,入棧
        while(!stack.isEmpty()){
            TreeNode cur = stack.pop();
            list.add(cur.val);
            if(cur.right!=null)
                stack.push(cur.right);
            if(cur.left != null)
                stack.push(cur.left);
        }
    }
    
    //中序遍歷
    public void inOrder(TreeNode root,List<Integer> list){
        if(root == null)
            return;
        //建立一個棧結構,將根節點作為當前結點
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode cur = root;
        //當棧不為空,並且當前結點不為空時
        while(!stack.isEmpty() || cur != null){
            //如果當前結點不為空,則將該節點入棧並且將指標移向左子樹
            if(cur != null){
                stack.push(cur);
                cur = cur.left;
            }else{
                //如果為空則彈出棧頂元素,並且將指標移向出棧結點的右子樹
                cur = stack.pop();
                list.add(cur.val);
                cur = cur.right;
            }
        }
    }
    
    //後序遍歷
    public void postOrder(TreeNode root,List<Integer> list){
        if(root == null)
            return;
        //建立一個棧結構,將根節點作為當前結點
        Stack<TreeNode> stack = new Stack<TreeNode>();
        //建立一個棧頂結點和一個標記結點
        TreeNode h = root, c = null;
        stack.push(root);
        while(!stack.isEmpty()){
            c = stack.peek();
            //如果標記結點的左子樹和右子樹都不為空,並且標記結點的左子樹和棧頂結點不同,說明標記結點的左子樹和右子樹都沒有處理過
            if(c.left != null && (c.left != h && c.right != h)){
                stack.push(c.left);
                c = c.left;
            }else if(c.right != null && c.right != h){  //如果c的右子樹不等於棧頂結點,說明右子樹沒有處理過
                stack.push(c.right);
                c = c.right;
            }else{                              //如果都處理了,則彈出棧頂元素並且將當前標記的節點置為棧頂元素。
                h = c;
                TreeNode tmp = stack.pop();
                list.add(tmp.val);
            }
        }
    }
}