94. 二叉树的中序遍历
给定一个二叉树,返回它的中序遍历。
Solution1(递归版):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> res; inorder(root,res); return res; } void inorder(TreeNode* node, vector<int> &res){ if(!node) return; inorder(node->left, res); res.push_back(node->val); inorder(node->right, res); } };
|
Solution2(迭代版):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: vector<int> inorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> ss; TreeNode* cur = root; while(cur || !ss.empty()){ if(cur){ ss.push(cur); cur = cur->left; } else{ cur = ss.top(); ss.pop(); res.push_back(cur->val); cur = cur->right; } } return res; } };
|
中序遍历的特点就是优先遍历左节点,之后是当前节点,最后是右节点。
所以遇到一个节点。先存储在栈内。考虑以下两点:
- 有左节点,继续加入栈。
- 没有左节点,处理该节点,并将该节点从栈中弹出,继续考虑该节点的右节点。
这里我在思考的时候,逻辑没有问题,在coding的时候,关注的是父节点与子节点的关系,这样写出来的代码很容易导致死循环(在左子节点判断玩后,无法弹出栈,下一层循环又继续进行左子节点的判断了)。看到评论是将每一个节点提出来作为观察对象。更加直接。