【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.
思路:
preorder用栈两三下就写完了
1 vector<int> preorderTraversal(TreeNode *root) { 2 vector<int> nodes; 3 if(root == NULL) return nodes; 4 stack<TreeNode *> tStack; 5 tStack.push(root); 6 while(!tStack.empty()){ 7 TreeNode *top = tStack.top(); 8 nodes.push_back(top->val); 9 tStack.pop(); 10 if(top->right != NULL) 11 tStack.push(top->right); 12 if(top->left != NULL) 13 tStack.push(top->left); 14 } 15 return nodes; 16 }
但是inorder不简单啊,模仿递归记录调用处然后处理完当前函数回来,下午困得不行闷头试了好几次各种bug超Memory,看了我是歌手回来发现脑子清醒了
1 vector<int> inorderTraversal(TreeNode *root) { 2 vector<int> nodes; 3 if(root == NULL) return nodes; 4 stack<TreeNode *> tStack; 5 TreeNode * cur = root; 6 while(!tStack.empty() || cur != NULL){//假如处理完根的左子树了,tStack也会为空 7 while(cur != NULL){ 8 tStack.push(cur);//只要当前节点有左孩子,则必须先去访问左子树,而当前节点就得入栈; 9 cur = cur->left; 10 } 11 cur = tStack.top();//如果当前节点为空怎么办?当然就访问它的父节点了,也就是栈顶元素; 12 tStack.pop(); 13 nodes.push_back(cur->val);//访问完栈顶元素之后就需要将当前节点置为栈顶元素的右孩子 14 cur = cur->right; 15 } 16 return nodes; 17 }
Postorder与Inorder很相似,但是比Inorder复杂的地方是如何判断该节点的左右子树都已经访问过了,按照Inorder的写法左子树还是先被访问,没有问题,但是访问完左子树后不能直接访问当前节点,要判断当前节点的右子树是否已经被访问,如果没有访问则应该继续去访问右子树,最后再访问当前节点
1 vector<int> postorderTraversal(TreeNode *root) { 2 vector<int> nodes; 3 if(root == NULL) return nodes; 4 stack<TreeNode *> tStack; 5 TreeNode *cur = root; //指向当前要检查的节点 6 TreeNode *previsited = NULL; //指向前一个被访问的节点 7 while (!tStack.empty() || cur != NULL) { 8 while (cur != NULL) { //只要cur有左孩子,则cur入栈,直到cur没有左孩子; 9 tStack.push(cur); 10 cur = cur->left; 11 } 12 cur = tStack.top(); 13 if (cur->right == NULL || cur->right == previsited) {//当前节点的右孩子如果为空或者已经被访问,则访问当前节点 14 tStack.pop();//后序遍历访问序列中,当前节点的前驱必然是其右孩子(如果有的话)) 15 nodes.push_back(cur->val); 16 previsited = cur; 17 cur = NULL; 18 }else { //否则访问右孩子,继续上述过程 19 cur = cur->right; 20 } 21 } 22 return nodes; 23 }