今天日常刷Leetcode刷到了一个二叉树中序遍历的题。原题链接
通过示例可以很明显了解到何为中序遍历,同时打算用栈结构来实现。
中序遍历
可以看作将节点投影到一个水平坐标轴上,从原点开始向右遍历。
如图顺序为:H->D->I->B->E->J->A->F->K->C->G
栈
栈遵循先进后出的原则。
把栈想象成一个桶:a1先入栈,被压在最底下;然后a2再入栈,压在a1的上面……
如何取出里面的数据呢?拿走最上面的元素,也就是出栈。被压在最底下的元素最后才能被拿出来。
例如: 入栈顺序 = 1, 2, 3, 4
出栈顺序 = 4, 3, 2, 1
明白概念之后就到了实现这个操作了。
思路
我使用了栈结构以及访问标记来实现。每个节点都附带一个名为visited的bool值(默认false)。
先让根节点入栈(栈里面没元素怎么出栈)
然后一直循环直到栈内元素全部出来。
中途如果发现是空节点就continue回到循环开始的地方。
如果这个节点没被访问过,那么就先标记一下已被访问visited=true
。
然后分别按顺序让右节点->当前节点->左节点入栈。(因为要中序遍历,所以如此入栈后出栈的顺序就是左节点->当前节点->右节点)
如果当前节点已经访问过了,那么就直接返回当前节点的值。
代码 (C++)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include <vector> #include <iostream> #include <stack> #include <unordered_map> using namespace std;
struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {} };
class Solution { public: vector<int> inorderTraversal(TreeNode* root) { stack<TreeNode*> s; unordered_map<TreeNode*, bool> umap{{nullptr, false}}; vector<int> res; s.push(root); TreeNode* temp; while (!s.empty()) { temp = s.top(); s.pop(); if (!temp) continue; if (umap[temp]) res.push_back(temp->val); else { umap[temp] = true; s.push(temp->right); s.push(temp); s.push(temp->left); } } return res; } };
|