树的三种遍历方式--模拟系统栈方式(通用)

树的三种遍历方式--模拟系统栈方式(通用)

LeetCode 144. 二叉树的中序遍历

题目描述:

给定一个二叉树,返回它的前序遍历。(非递归实现)

题目分析:

可以模拟系统栈,实现进栈、出栈操作,从而实现原递归的思想。定义两个状态:访问+输出。

/**
 * 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> inorderTraversal(TreeNode* root) {
            //采用模拟系统栈的情况进行实现,呈现出真是的入栈、出栈操作
            vector<int>res;
            if(root==NULL)
                return res;
            
            bool state=1;  //这里state表示的状态,1的话是打印结点,2的话是访问下一个结点。
            struct Commend
            {
                bool st;
                TreeNode* p;
                Commend(bool st,TreeNode *p):st(st),p(p){}  //注意要写好初始化形式
            };
            
            stack<Commend>s;
            s.push(Commend(0,root));
            
            while(!s.empty())
            {
                Commend cur=s.top();
                s.pop();
                
                if(cur.st==true)
                    res.push_back(cur.p->val);
                else                            //模拟的进栈操作(注意顺序--和遍历次序相反--先进后出)
                {
                    if(cur.p->right)              //右孩子入栈
                        s.push(Commend(0,cur.p->right));    

                    if(cur.p->left)              //左孩子入栈
                        s.push(Commend(0,cur.p->left));
                        
                    s.push(Commend(1,cur.p));    //根结点入栈         (反过来的次序正好是:根-左-右)前序
                }
            }
            return res;
    }
};

LeetCode94. 二叉树的中序遍历

题目描述:

给定一个二叉树,返回它的中序 遍历。(非递归实现)

题目分析:

可以模拟系统栈,实现进栈、出栈操作,从而实现原递归的思想。定义两个状态:访问+输出。

/**
 * 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> inorderTraversal(TreeNode* root) {
            //采用模拟系统栈的情况进行实现,呈现出真是的入栈、出栈操作
            vector<int>res;
            if(root==NULL)
                return res;
            
            bool state=1;  //这里state表示的状态,1的话是打印结点,2的话是访问下一个结点。
            struct Commend
            {
                bool st;
                TreeNode* p;
                Commend(bool st,TreeNode *p):st(st),p(p){}  //注意要写好初始化形式
            };
            
            stack<Commend>s;
            s.push(Commend(0,root));
            
            while(!s.empty())
            {
                Commend cur=s.top();
                s.pop();
                
                if(cur.st==true)
                    res.push_back(cur.p->val);
                else                            //模拟的进栈操作(注意顺序--和遍历次序相反--先进后出)
                {
                    if(cur.p->right)              //右孩子入栈
                        s.push(Commend(0,cur.p->right));    
                    
                    s.push(Commend(1,cur.p));    //根结点入栈         (反过来的次序正好是:左-根-右)中序

                    if(cur.p->left)              //左孩子入栈
                        s.push(Commend(0,cur.p->left));

                }
            }
            return res;
    }
};

LeetCode145. 二叉树的中序遍历

题目描述:

给定一个二叉树,返回它的后序 遍历。(非递归实现)

题目分析:

可以模拟系统栈,实现进栈、出栈操作,从而实现原递归的思想。定义两个状态:访问+输出。

/**
 * 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> inorderTraversal(TreeNode* root) {
            //采用模拟系统栈的情况进行实现,呈现出真是的入栈、出栈操作
            vector<int>res;
            if(root==NULL)
                return res;
            
            bool state=1;  //这里state表示的状态,1的话是打印结点,2的话是访问下一个结点。
            struct Commend
            {
                bool st;
                TreeNode* p;
                Commend(bool st,TreeNode *p):st(st),p(p){}  //注意要写好初始化形式
            };
            
            stack<Commend>s;
            s.push(Commend(0,root));
            
            while(!s.empty())
            {
                Commend cur=s.top();
                s.pop();
                
                if(cur.st==true)
                    res.push_back(cur.p->val);
                else                            //模拟的进栈操作(注意顺序--和遍历次序相反--先进后出)
                {
                    s.push(Commend(1,cur.p));    //根结点入栈         (反过来的次序正好是:左-右-根)后序
                    
                    if(cur.p->right)              //右孩子入栈
                        s.push(Commend(0,cur.p->right));    

                    if(cur.p->left)              //左孩子入栈
                        s.push(Commend(0,cur.p->left));
                }
            }
            return res;
    }
};

总结:采用模拟系统栈的方法进行解决,三种树的遍历次序归根结底就是入栈的次序不同,只需要调整入栈的次序即可。

猜你喜欢

转载自blog.csdn.net/qq_20110551/article/details/81536215