樹的前中後序遍歷定義:
前:中左右
中:左中右
後:左右中
遞歸版本非常好寫,這裏不再贅述,僅考慮非遞歸使用棧進行遍歷
首先來看節點結構
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
以前學的版本
中序
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ret;
stack<TreeNode*> stk;
while (!stk.empty() || root != NULL) {
if (root != NULL) {
stk.push(root);
root = root->left;
}
else {
root = stk.top();
stk.pop();
ret.push_back(root->val);
root = root->right;
}
}
return ret;
}
};
前序
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ret;
stack<TreeNode*> stk;
while (!stk.empty() || root != NULL) {
if (root != NULL) {
ret.push_back(root->val);
stk.push(root);
root = root->left;
}
else {
root = stk.top();
stk.pop();
root = root->right;
}
}
return ret;
}
};
這兩種前中序的非遞歸遍歷寫法也是主流的寫法,差別也僅有ret.push_back(root->val);
訪問節點這一句話的位置不同,但這種寫法是沒有辦法寫樹的後序遍歷的。
船新的版本
其核心就是在棧中使用了pair
二元組來標記這是第幾次被訪問,其實就是完完全全地模擬了遞歸的寫法。
後序:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ret;
stack<pair<TreeNode*, int>> stk;
if (root)
stk.push({root, 0});
while (!stk.empty()) {
pair<TreeNode*, int> cur = stk.top();
if (cur.second == 0) { // 第零次被訪問
stk.top().second = 1; // 標記爲1
if (cur.first->left)
stk.push({cur.first->left, 0});
}
else if (cur.second == 1) { // 第一次被訪問
stk.top().second = 2; // 標記位2
if (cur.first->right)
stk.push({cur.first->right, 0});
}
else if (cur.second == 2) { // 第二次被訪問
ret.push_back(cur.first->val);
stk.pop();
}
}
return ret;
}
};
中序:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ret;
stack<pair<TreeNode*, int>> stk;
if (root)
stk.push({root, 0});
while (!stk.empty()) {
pair<TreeNode*, int> cur = stk.top();
if (cur.second == 0) {
stk.top().second = 1;
if (cur.first->left)
stk.push({cur.first->left, 0});
}
else if (cur.second == 1) {
stk.top().second = 2;
ret.push_back(cur.first->val);
}
else if (cur.second == 2) {
stk.pop();
if (cur.first->right)
stk.push({cur.first->right, 0});
}
}
return ret;
}
};
前序
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ret;
stack<pair<TreeNode*, int>> stk;
if (root)
stk.push({root, 0});
while (!stk.empty()) {
pair<TreeNode*, int> cur = stk.top();
if (cur.second == 0) {
stk.top().second = 1;
ret.push_back(cur.first->val);
}
else if (cur.second == 1) {
stk.top().second = 2;
if (cur.first->left)
stk.push({cur.first->left, 0});
}
else if (cur.second == 2) {
stk.pop();
if (cur.first->right)
stk.push({cur.first->right, 0});
}
}
return ret;
}
};