题目描述
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;
}
};
需要注意的是,因为需要先处理左子树结点,再处理右子树结点,所以需要将右子树根节点先入栈,再将左子树根节点入栈。