前序遍历【中左右】:
思路
- 先不断搜寻左结点,同时将数值压入返回数组则实现了根先压入再压左子结点的情况。
- 直到到了左叶子结点,则从stack中取出一个结点,开始搜寻该结点的右子树部分,右子树部分重复步骤1。
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode *cur = root;
stack<TreeNode*> stk;
while (cur||!stk.empty()){
while (cur){
stk.push(cur);
res.push_back(cur->val);
cur=cur->left;
}
if (!stk.empty()){
cur = stk.top();
stk.pop();
}
if (cur) cur = cur->right;
}
return res;
}
中序遍历【左中右】:
思路:
- 先不断搜寻左子结点,但我们不像前序遍历一样直接将数值压入,而是不断地搜寻(因为如果我们搜寻时便压入数值,则会变成【中左右】的情况)。
- 取出栈顶元素,压入目标值【左】(其实为该子树的根即【中】),搜寻右子树重复步骤一。
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode *cur = root;
stack<TreeNode*> stack;
while (cur||!stack.empty()){
while (cur){
stack.push(cur);
cur = cur->left;
}
cur = stack.top();
res.push_back(cur->val);
stack.pop();
cur = cur->right;
}
return res;
}
后序遍历【左右中】:
与前序遍历思想相同,但是我们需要改变一下输出顺序
前序遍历我们得到的序列为【中左右】如果用栈压入后输出则【右左中】,离我们要的【左右中】只有前两个元素的差别,故而我们在前序遍历的序列中改变顺序【中右左】,经过栈后则变为【左右中】为我们所求。
- 不断搜寻右子树同时压入结点
- 搜索到叶子结点时,开始搜寻左子树,重复步骤1内容
- 将序列栈中的数值弹出,返回
vector<int> postorderTraversal(TreeNode* root) {
TreeNode *cur = root;
stack<TreeNode*> stk;
stack<int> res;
while (cur||!stk.empty()){
while (cur){
stk.push(cur);
res.push(cur->val);
cur=cur->right;
}
if (!stk.empty()){
cur = stk.top();
stk.pop();
}
if (cur) cur = cur->left;
}
vector<int> ret;
while (!res.empty()){
ret.push_back(res.top());
res.pop();
}
return ret;
}