二叉树的遍历有很多方法,首先想到的就是递归
解法一(递归):
void pre_order(TreeNode* root){ //先序
if(root==NULL) return ;
cout<<root->val<<endl;
pre_order(root->left);
pre_order(root->right);
}
void mid_order(TreeNode* root){ //中序
if(root==NULL) return ;
mid_order(root->left);
cout<<root->val<<endl;
mid_order(root->right);
}
void last_order(TreeNode* root){ //后序
if(root==NULL) return ;
last_order(root->left);
last_order(root->right);
cout<<root->val<<endl;
}
解法二(染色法,非递归):
当当前的node的颜色为0时,代表该节点还没访问,若node的颜色为1时,代表该节点已访问。当遇到颜色为1的node直接输出即可;遇到颜色为0的节点,把该节点颜色变为灰色,然后和该节点的左右儿子节点一起拉入栈中。(压栈顺序和要求的先序、中序、后序遍历有关)。
struct point{
int color;
TreeNode* node;
point(TreeNode* newNode,int c){
color=c;
node=newNode;
}
};
void pre_order(TreeNode* root) {//当然其实先序遍历不需要染色了,因为访问到那个就输出那个就行了
if(root==NULL) return ;
vector<point> ve;
ve.push_back(point(root,0));
while(!ve.empty()){
point tmp=ve.back();
ve.pop_back();
if(tmp.color==0){
if(tmp.node->right) ve.push_back(point(tmp.node->right,0));
if(tmp.node->left) ve.push_back(point(tmp.node->left,0));
ve.push_back(point(tmp.node,1));
}else cout<<tmp.node->val<<endl;;
}
}
void mid_order(TreeNode* root) {
if(root==NULL) return ;
vector<point> ve;
ve.push_back(point(root,0));
while(!ve.empty()){
point tmp=ve.back();
ve.pop_back();
if(tmp.color==0){
if(tmp.node->right) ve.push_back(point(tmp.node->right,0));
ve.push_back(point(tmp.node,1));
if(tmp.node->left) ve.push_back(point(tmp.node->left,0));
}else cout<<tmp.node->val<<endl;;
}
}
void last_order(TreeNode* root) {
if(root==NULL) return ;
vector<point> ve;
ve.push_back(point(root,0));
while(!ve.empty()){
point tmp=ve.back();
ve.pop_back();
if(tmp.color==0){
ve.push_back(point(tmp.node,1));
if(tmp.node->right) ve.push_back(point(tmp.node->right,0));
if(tmp.node->left) ve.push_back(point(tmp.node->left,0));
}else cout<<tmp.node->val<<endl;;
}
}
void pre_order(TreeNode* root){
if(root==NULL) return ;
vector<TreeNode*> ve;
ve.push_back(root);
while(!ve.empty()){
cout<<ve.back()->val<<endl;
ve.pop_back();
if(root->right) ve.push_back(root->right);
if(root->left) ve.push_back(root->left);
}
}