但是也可以用迭代。迭代中当先序遍历时 实际上是用队列是可以实现的,而中序遍历和后序遍历却无法用队列实现,而是需要用到栈,原因在于,我们在遍历一个节点时,并不马上输出它,而是先要去遍历它的左孩子(中序),或者左右孩子(后续)。这就是队列所无法解决的问题。
对于中序遍历,我们可以一直对节点的左子树入栈,也就是说每次入栈,我们都将其左子树遍历完了。等到我们需要出栈的时候,我们会检查栈顶元素是否有右子树,如果有就将右子树及其它的左子树全部全部入栈,弹出节点即可。
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<int> result(0);
if (root == NULL)
return result;
stack<TreeNode*> stk;
TreeNode* cur = root;
while(cur){
stk.push(cur);
cur=cur->left;
}
while(!stk.empty()){
cur=stk.top();
stk.pop();
result.push_back(cur->val);
cur=cur->right;
while(cur){
stk.push(cur);
cur=cur->left;
}
}
return result;
}
};
而对于后序遍历 则没有办法那么直接,因为后序遍历需要我们在输出本节点之前先输出左子树和右子树,我们在栈顶得到一个元素的时候,没有办法确定这个元素是否已经访问过它的子树了(而中序遍历可以知道的原因是,我们知道当元素出现在栈顶时,它的左子树必须是已经被访问过了)
当然我们也有办法去知道它是否被遍历过,一个非常简单的想法,是为每个树节点设置一个标记位
如果这个节点已经被访问过之后,就输出,否则将左右子树入栈,设计标记位为已经访问过。
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector <int> travel;
subpost(travel,root);
return travel;
}
void subpost(vector <int> & travel,TreeNode * root){
if(root==NULL){
return ;
}
stack <TreeNode *> s;
stack <bool>ss;
TreeNode * cur;
TreeNode * prev=NULL;
ss.push(false);
s.push(root);
cur=root;
int count=0;
while(!s.empty()){
cur=s.top();
if(!cur->left&&!cur->right){
travel.push_back(cur->val);
s.pop();
ss.pop();
continue;
}
if(ss.top()==true){
travel.push_back(cur->val);
s.pop();
ss.pop();
}
else{
ss.top()=true;
if(cur->right){
s.push(cur->right);
ss.push(false);
}
if(cur->left){
s.push(cur->left);
ss.push(false);
}
}
}
}
};
本章最后一题:
Binary Tree Maximum Path Sum
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
树的最长路径,按照树的结构,可以写出下面算法,最长路径,
或者 1.与本节点所在的路径相关,此时也有两种情况,一是本节点连接的左右子树一起作为最长的路径,本节点还需要依赖父亲节点构成最长路径
2与本节点无关,
有没有关系只要用max这个函数就可以解决。
class Solution {
public:
int maxPathSum(TreeNode *root) {
int chain=0,value=0,maxx=root->val;
submax(root,chain,maxx);
return maxx;
}
void submax(TreeNode *node,int &chain,int &maxx){
int chainl=0,chainr=0;
if(node==NULL){
return;
}
submax(node->left,chainl,maxx);
submax(node->right,chainr,maxx);
maxx=max(chainl+chainr+node->val,maxx);
chain=max(chainl,chainr);
chain=max(0,chain+node->val);
}
};