总结一下二叉树的遍历,利用模板的写法来写。
二叉树的遍历分两种:
DFS:先序,中序,后续 ---->利用栈stack
BFS:层序 ---->利用队列queue
层序遍历比较简单,LeetCode没有专门的题目,简单说就是一个queue往里面添加节点,其实就是宽度优先搜索。
这里只为了面试的方便,三序遍历采用模板的形式写出。面试时候要考非递归自己乱写还是容易出错,老老实实根据模板背下来,反正遇到复杂题目也不会用非递归,应试吧!
模板形式:
if(p){
...
}
else{
...
}
总结一下:解答别人已经写得非常详细了。我就写一点怎么记下来的应试吧。。。
- 先序遍历的顺序:根-左-右。所以在if{...}中间肯定要先把当前访问的节点p给添加到vector中。同时添加到stack中,并且去访问p->left(去访问左侧的节点),然后在else{...}中就直接去访问右节点才对,但是此时p已经是NULL,所以要从栈中取出栈顶s.top(),然后去访问其右侧节点就可以了。
- 中序遍历的顺序:左-根-右。所以在if{...}中间要一直向左去找下去,并且把每一个都添加到stack中(root,root->left,...),在else{...}中,则表示现在已经找到最左侧了,但是此时p又成NULL了,所以要取出栈顶元素,p = s.top()。然后再去找右侧的节点。
- 后续遍历顺序:左-右-根,但是如果你按照根-右-左的顺序访问,每次把新得到值插入vector最前面就可以了(使用insert)。额....画个图就能理解了。跟先序遍历一样。
- 写完了之后仔细想想这个模板跟递归法的写法差不多?就好像先序,除去其它的压栈弹栈操作,不就是:先访问了当前的p->val,再访问左节点p=p->left,再去访问右节点p = p->right。其它的自己类比下吧。。。
- 一个非常重要的点,这种写法的循环条件:while(p || !s.empty())不用先存入一个root结点到stack s中。
前序遍历
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
if(!root) return {};
stack<TreeNode*> s;//不用先存入一个root结点到s中
vector<int> res;
TreeNode* p = root;
while(p || !s.empty()){
if(p){
res.push_back(p->val);
s.push(p);
p = p->left;
}
else{
p = s.top();
s.pop();
p = p->right;
}
}
return res;
}
};
中序遍历
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
if(!root) return {};
stack<TreeNode*> s;
vector<int> res;
TreeNode* p = root;
while(p || !s.empty()){
if(p){
s.push(p);
p = p->left;
}
else{
p = s.top();
s.pop();
res.push_back(p->val);
p = p->right;
}
}
return res;
}
};
后序遍历
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
if(!root) return {};
stack<TreeNode*> s;
vector<int> res;
TreeNode* p = root;
while(p || !s.empty()){
if(p){
res.insert(res.begin(),p->val);
s.push(p);
p=p->right;
}
else{
p = s.top();
s.pop();
p = p->left;
}
}
return res;
}
};
层序遍历:
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
if (!root) return {};
vector<int> res;
queue<TreeNode*> q;q.push(root);
while (!q.empty()) {
TreeNode *t = q.front(); q.pop();
res.push_back(t->val);
if (t->left) q.push(t->left);
if (t->right) q.push(t->right);
}
}
return res;
}
};
剑指offer第60题:分层打印二叉树