1. 程式人生 > >LeetCode(48) Binary Tree Preorder Traversal

LeetCode(48) Binary Tree Preorder Traversal

題目描述

Given a binary tree, return the preorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},
二叉樹
return [1,2,3].

本題要求對二叉樹進行先序遍歷,所謂先序遍歷:根-左-右,先遍歷根結點,再遍歷左子樹,最後遍歷右子樹。

遞迴求解

二叉樹的遍歷最簡單的方法就是遞迴處理,無論是先序遍歷、中序遍歷還是後序遍歷都可以通過遞迴得到。

1 先序遍歷:先訪問根節點,再遞迴訪問左子樹 ,最後遞迴訪問右子樹;
2 中序遍歷:先遞迴訪問左子樹,再訪問根節點,最後遞迴訪問右子樹;
3 後序遍歷:先遞迴遍歷左子樹,再遞迴遍歷右子樹,最後遍歷根節點。

先序遍歷程式碼如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void traversal(TreeNode* node, vector<int>& node_value)
    {
        if
(node == NULL) return; node_value.push_back(node->val); traversal(node->left, node_value); traversal(node->right, node_value); } vector<int> preorderTraversal(TreeNode* root) { vector<int> node_value; if(root == NULL) return node_value; traversal(root, node_value); return
node_value; } };

所以中序遍歷和後續遍歷和先序遍歷不同的地方主要是訪問結點的位置。
1 先序遍歷:

node_value.push_back(node->val);
traversal(node->left, node_value);
traversal(node->right, node_value);

2 中序遍歷

traversal(node->left, node_value);
node_value.push_back(node->val);
traversal(node->right, node_value);

3 後序遍歷

traversal(node->left, node_value);
traversal(node->right, node_value);
node_value.push_back(node->val);

非遞迴解法

使用遞迴思路簡單,但是也存在其他問題,例如遞迴的函式呼叫會產生代價,並且如果樹的層次非常高時也可能會引起棧溢位的問題。因此,這裡再給出非遞迴的解法。非遞迴的解法需要使用一個棧儲存待處理的結點。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> node_value;
        if(root == NULL) return node_value;

        stack<TreeNode*> nodes;
        nodes.push(root);
        while(!nodes.empty())
        {
            TreeNode* top = nodes.top();
            nodes.pop();
            node_value.push_back(top->val);
            if(top->right!=NULL) nodes.push(top->right);
            if(top->left != NULL) nodes.push(top->left);
        }

        return node_value;
    }
};

需要注意的是,因為需要先處理左子樹結點,再處理右子樹結點,所以需要將右子樹根節點先入棧,再將左子樹根節點入棧。