【LeetCode】Binary Tree Preorder &Inorder & Postorder Traversal

来源:互联网 发布:50 seo 编辑:程序博客网 时间:2024/05/01 15:18

先序遍历


递归方法:
这个方法简单,只要按照 自己-> 右儿子 -> 左儿子的顺序就可以了

非递归法,开始时根结点在栈中,然后
{
栈顶输弹出
如果有右儿子,右儿子入栈
如果有左儿子,左儿子入栈
}
这样循环,直到栈为空。栈顶一直是下一个要打印的根结点。

#if METHOD == 1/*这里对vector的使用方法要得当,把两个vector拼在一起的方法是把out1,out2,拼成(out1,out2) out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错 */class Solution {public:    vector<int> preorderTraversal(TreeNode *root) {//中左右         vector<int> out;        if(root == NULL)        return out;                vector<int> out1 = preorderTraversal(root->left);        vector<int> out2 = preorderTraversal(root->right);                        out.insert(out.begin(),out2.begin(),out2.end());//右         out.insert(out.begin(),out1.begin(),out1.end());//左         out.insert(out.begin(),root->val); //中                 return out;    }};#elif METHOD == 2//堆栈方法 //这个方法不太好理解,需要加以研究 class Solution {public:    vector<int> preorderTraversal(TreeNode *root) {        vector<int> out;        if(root == NULL)        return out;       //TreeNode *head = root;//就是记录上一个弹出的结点        treenodeStack.push(root);        while(!treenodeStack.empty()){TreeNode *cur = treenodeStack.top();//增加一个记录点treenodeStack.pop();out.push_back(cur->val);if(cur->right != NULL)treenodeStack.push(cur->right)/*,printf("lpush = %d\n",cur->right->val)*/;if(cur->left != NULL)treenodeStack.push(cur->left)/*,printf("rpush = %d\n",cur->left->val)*/;}         return out;    }private:stack<TreeNode*> treenodeStack; };#endif


中序遍历


中序遍历二叉树:
递归法,不多说,左孩子-》自己-》右孩子这样递归就可以了。

循环法:使用栈,下面的代码还是比较好的。
其中指针p的使用非常关键
#if 0class Solution {public://中序遍历,左中右     vector<int> inorderTraversal(TreeNode *root) {vector<int> out;        if(root == NULL)      return out;                vector<int> outleft = inorderTraversal(root->left);        vector<int> outright = inorderTraversal(root->right);out.insert(out.begin(),outright.begin(),outright.end());out.insert(out.begin(),root->val);out.insert(out.begin(),outleft.begin(),outleft.end());        return out;    }};#elif 1//栈 ------------赞!!!! class Solution {public://中序遍历,左中右     vector<int> inorderTraversal(TreeNode *root) {vector<int> out;        stack<TreeNode *> stk;       TreeNode *p = root;       while(!stk.empty() || p)       {       if(p != NULL)       {       stk.push(p);       p = p->left;  }  else  {p = stk.top();stk.pop();out.push_back(p->val);p = p->right;  }  }               return out;    }};#endif 


后序遍历


递归方法:
这个方法简单,只要按照左儿子 -> 右儿子 -> 自己的顺序就可以了

非递归方法1:
相比于前序遍历,后续遍历思维上难度要大些,前序遍历是通过一个stack,首先压入父亲结点,然后弹出父亲结点,并输出它的value,之后压人其右儿子,左儿子即可。然而后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:第一,它已经是叶子结点;第二,它不是叶子结点,但是它的儿子已经输出过(代码里非递归方法head就是用来记录访问过的儿子的)。那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。



非递归方法2:

利用堆栈很按后序的逆序输入再做一次逆序

从一开始,就按 自己->右儿子->左儿子顺序输出,最后做一下逆序就好

#if METHOD == 1/*这里对vector的使用方法要得当,把两个vector拼在一起的方法是把out1,out2,拼成(out1,out2) out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错 */class Solution {public:    vector<int> postorderTraversal(TreeNode *root) {        vector<int> out;        if(root == NULL)        return out;                vector<int> out1 = postorderTraversal(root->left);        vector<int> out2 = postorderTraversal(root->right);                out.insert(out.begin(),root->val); //中         out.insert(out.begin(),out2.begin(),out2.end());//右         out.insert(out.begin(),out1.begin(),out1.end());//左         return out;    }};#elif METHOD == 2//堆栈方法 //这个方法不太好理解,需要加以研究 class Solution {public:    vector<int> postorderTraversal(TreeNode *root) {        vector<int> out;        if(root == NULL)        return out;       TreeNode *head = root;//就是记录上一个弹出的结点        treenodeStack.push(root);        while(!treenodeStack.empty()){TreeNode *cur = treenodeStack.top();//增加一个记录点if(cur->left == head || cur->right== head ||(cur->left == NULL && cur->right == NULL))//这个条件很关键 {treenodeStack.pop();out.push_back(cur->val);head = cur;//printf("pop = %d\n",cur->val);//system("pause");} else{if(cur->right != NULL)treenodeStack.push(cur->right)/*,printf("lpush = %d\n",cur->right->val)*/;if(cur->left != NULL)treenodeStack.push(cur->left)/*,printf("rpush = %d\n",cur->left->val)*/;}}         return out;    }private:stack<TreeNode*> treenodeStack; };#elif METHOD == 3/*这个方法赞呀!自己->右儿子->左儿子顺序输出,最后做一下逆序就好 */class Solution {public:    vector<int> postorderTraversal(TreeNode *root) {        vector<int> res;        if(root == NULL)            return res;        vector<TreeNode*> stc;        stc.push_back(root);        while(!stc.empty()) {            TreeNode* node = stc.back();            res.push_back(node->val);            stc.pop_back();            if(node->left != NULL) {                stc.push_back(node->left);            }            if(node->right != NULL) {                stc.push_back(node->right);            }        }        reverse(res.begin(), res.end());        return res;    }}; #endif


                                             
0 0