二叉樹的各種遍歷姿勢

前言

Node節點

public static class TreeNode {
    TreeNode left;
    TreeNode right;
    int val;
}

定義

  • 先序遍歷:先訪問根,再訪問左子樹,最後訪問右子樹
  • 中序遍歷:先訪問左子樹,再訪問根,最後訪問右子樹
  • 後序遍歷:先訪問左子樹,再訪問右子樹,最後訪問根

遞歸式模板

public static List<Integer> view(TreeNode root, List<Integer> result) {
    if(null == root) {
        return result;
    }
    result.add(root.val);     // 根
    view(root.left, result);  // 左
    // result.add(root.val);
    view(root.right, result); // 右
    // result.add(root.val);
    return result;
}

由根的訪問時機可以得到不同的遍歷順序,根左右爲先序,左根右爲中序,左右根爲後序

非遞歸式模板

先序、中序

public static List<Integer> view(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while (null != cur || !stack.isEmpty()) {
        if (null != cur) {
            stack.push(cur);     // 入棧
            result.add(cur.val); // 訪問(先序)
            cur = cur.left;      // 左行
        } else {
            cur = stack.pop();   // 出棧
            // result.add(cur.val); // 訪問(中序)
            cur = cur.right;     // 右行
        }
    }

    return result;
}

入棧和左行之間訪問節點,得到的是先序
出棧和右行之間訪問節點,得到的是中序

後序

public static List<Integer> view(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Stack<TreeNode> tmp = new Stack<>();     // 輔助棧
    Stack<TreeNode> stack = new Stack<>();   // 主棧
    
    tmp.push(root);
    TreeNode cur = null;
    while (!tmp.isEmpty()) {
        // 從輔助棧取一個節點
        cur = tmp.pop();

		// 依次將其左右節點入輔助棧
        if (null != cur.left) {
            tmp.push(cur.left);
        }
        if (null != cur.right) {
            tmp.push(cur.right);
        }

		// 當前節點入主棧
        stack.push(cur);
    }
    
    while (!stack.isEmpty()) {
        result.add(stack.pop().val);
    }

    return result;
}

從輔助棧取出一個節點,依次將其左節點–>右節點壓入輔助棧,再將本身壓入主棧,循環至輔助棧空。
最後從主棧取出,根據棧性質易知得到的是左–>右–>根的順序,即爲後序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章