Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [1,2,3]
.
Note: Recursive solution is trivial, could you do it iteratively?
先序遍历的基本思想就是先访问根元素,再访问左子树,然后访问右子树。
那么递归的代码就很容易实现,如下:
/**
* Definition for binary tree
* 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> ans;
preOrder(root, ans);
return ans;
}
void preOrder(TreeNode* root, vector<int>& v)
{
if( root )
{
v.push_back(root->val);
preOrder(root->left, v);
preOrder(root->right, v);
}
}
};
迭代的方式呢?递归转化为迭代的方式,总是可以用栈来实现,不过就是不好理解。不过观察递归的方式,程序是访问根元素,然后再访问“左子树”,接着继续访问“右子树”,那么在栈中的存放方式,应该是取出,访问,然后先放入“右子树”,再放入“左子树”。
其他就需要看代码体会了~~~~~~
/**
* Definition for binary tree
* 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) {
if( !root )
return vector<int>();
vector<int> ans;
stack<TreeNode*> st;
st.push(root);
while( !st.empty() ) {
TreeNode* p = st.top();
st.pop();
ans.push_back(p->val);
if( p->right )
st.push(p->right);
if( p->left )
st.push(p->left);
}
return ans;
}
};
Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [1,3,2]
.
Note: Recursive solution is trivial, could you do it iteratively?
confused what "{1,#,2,3}"
means? > read more on how binary tree is serialized on OJ.
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> ans;
inorder(ans, root);
return ans;
}
void inorder(vector<int>& v, TreeNode* root) {
if( !root )
return ;
inorder(v, root->left);
v.push_back(root->val);
inorder(v, root->right);
}
};
坑爹的迭代方式,记住节点被访问的条件是以其为根的二叉树的左子树被访问完了,这时该节点才被访问。
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> ans;
if(!root)
return ans;
stack<TreeNode*> st;
TreeNode* ptree = root;
while( ptree ) { //从根元素开始,将左孩子依次放入栈中
st.push(ptree);
ptree = ptree->left;
}
while( !st.empty() ) {
ptree = st.top(); //每次取出的节点都是未访问的最左节点
st.pop();
ans.push_back(ptree->val); //取出元素访问
ptree = ptree->right; //这时可以认为这个节点为根的子树的左子树已访问完,根元素也访问完
while( ptree ) { //从右子树的根节点开始,依次放入节点至栈中
st.push(ptree);
ptree = ptree->left;
}
}
return ans;
}
};
Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3}
,
1 \ 2 / 3
return [3,2,1]
.
Note: Recursive solution is trivial, could you do it iteratively?
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> v;
postOrder(root, v);
return v;
}
void postOrder(TreeNode* root, vector<int>& v) {
if( root ) {
postOrder(root->left, v);
postOrder(root->right, v);
v.push_back(root->val);
}
}
};
迭代的方式非常不好理解,说下一般步骤:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> ans;
if( !root )
return ans;
stack<TreeNode*> s;
s.push(root); //压入根节点
TreeNode* pPre = NULL;
while( !s.empty() ) {
TreeNode* pCur = s.top();
if( ( pCur->left == NULL && pCur->right == NULL ) //若当前节点左右孩子均为空 或 前驱节点等于当前节点左孩子或右孩子
|| ( pPre != NULL && ( pPre == pCur->left || pPre == pCur->right ) ) ) {
ans.push_back( pCur->val ); //则访问
pPre = pCur;
s.pop();
}
else { //否则先放入右孩子,再放入左孩子
if( pCur->right )
s.push( pCur->right );
if( pCur->left )
s.push( pCur->left );
}
}
return ans;
}
};