二叉树的遍历应该是一个基本操作,有很多相关的题目,这篇文章就用几种不同的方法来实现遍历整个遍历过程。
先定义一下二叉树的节点:
struct TreeNode {
* int val;
* TreeNode *lc;
* TreeNode *rc;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
首先就是深度优先搜索(DFS)
DFS分为先序遍历,中序遍历,后序遍历三种方式,每一种方式可以用递归和迭代来实现。
**先序遍历
递归版
void traverse(TreeNode *x,VST &visit)
{
if(!x)return;
visit(x->val);
traverse(x->lc,vst);
traverse(x->rc,vst);
}
迭代版
void vistalong(TreeNode* x,stack<TreeNode* >&st,VST &visit)
{
while(x)
{
visit(x->val);
st.push(x->right);
x=x->lc;
}
}
void traverse(TreeNode* root,VST &visit)
{
stack<TreeNode* >s;
while(true)
{
visitalong(root,s,visit);
if(s.empty())break;
s.pop();
}
}
中序遍历
递归版
void traverse(TreeNode *x,VST &visit)
{
if(!x)return;
traverse(x->lc,vst);
visit(x->val);
traverse(x->rc,vst);
}
迭代版
void vistalong(TreeNode* x,stack<TreeNode* >&st,VST &visit)
{
while(x)
{
st.push(x);
x=x->lc;
}
}
void traverse(TreeNode* root,VST &visit)
{
stack<TreeNode* >s;
while(true)
{
visitalong(root,s,visit);
if(s.empty())break;
root=s.top();
visit(root->val);
root=root->rc;
s.pop();
}
}
后序遍历
递归版
void traverse(TreeNode *x,VST &visit)
{
if(!x)return;
traverse(x->lc,vst);
traverse(x->rc,vst);
visit(x->val);
}
迭代版
我们以LeetCode145题为例进行说明,这是一道hard题,题目明确要求使用迭代方法完成对二叉树的后序遍历。
代码实现:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*>s;
vector<int>vi;
if(root) s.push(root);
while(!s.empty())
{
if(s.top()->right!=root&&s.top()->left!=root)
visitalong(s);
root=s.top();
vi.push_back(root->val);
s.pop();
}
return vi;
}
void visitalong(stack<TreeNode*>&s)
{
while(auto x=s.top())
if(x->left)
{
if(x->right)
{
s.push(x->right);
}
s.push(x->left);
}
else s.push(x->right);
s.pop();
}
};
宽度优先搜索(BFS)
以LeetCode102题为例,这是一道medium难度题。
递归版(借用先序遍历的思路)
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vist(root,0);
return vi;
}
void vist(TreeNode* r,int deepth)
{
if(r==0)return;
if(deepth==vi.size()){vi.push_back(*(new vector<int>));}
vi[deepth].push_back({r->val});
vist(r->left,deepth+1);
vist(r->right,deepth+1);
}
vector<vector<int>>vi;
};
迭代版
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root)return vi;
queue<TreeNode*>qt,qy;
vector<int>temp;
qt.push(root);
while(!qt.empty())
{
auto x=qt.front();qt.pop();
temp.push_back(x->val);
if(x->left) qy.push(x->left);
if(x->right) qy.push(x->right);
if(qt.empty())
{
vi.push_back(temp);
temp={};
qt.swap(qy);
}
}
return vi;
}
vector<vector<int>> vi;
};