leetcode刷题之二叉树遍历(递归、迭代和层序)

二叉树的定义

1. 二叉树种类:

1.1 空的二叉树
1.2 只有根结点的二叉树
1.3 只有左子树或者右子树的二叉树
1.4 左右子树都存在的时候:
(1)满二叉树
(2)完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2 ( h − 1 ) 2^(h-1) 2(h1) 个节点。
在这里插入图片描述

2. 遍历方式

2.1前序遍历(根在前面)
2.2中序遍历(根在中间)
2.3后序遍历(根在后面)在这里插入图片描述

3.C++代码

struct TreeNode //链式储存二叉树
{
    
    
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {
    
    }
};

二叉树之递归遍历

1.前序遍历

题目 难度:简单

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    void Traversal(TreeNode *cur,vector<int> &vec)
    {
    
    
        if(cur==nullptr)
        {
    
    
            return;//相当于中断,意思是只要cur=null,就退出Traversal函数
        }
        vec.push_back(cur->val);//中
        Traversal(cur->left,vec);
        Traversal(cur->right,vec);
    }
    vector<int> preorderTraversal(TreeNode* root) 
    {
    
    
        vector<int> vec;
        Traversal(root,vec);
        return vec;
    }
};

2.中序遍历

题目 难度:简单

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    void Traversal(TreeNode *cur,vector<int> &vec)
    {
    
    
        if(cur==nullptr)
        {
    
    
            return;//相当于中断
        }
        Traversal(cur->left,vec);
        vec.push_back(cur->val);//中
        Traversal(cur->right,vec);
    }
    vector<int> preorderTraversal(TreeNode* root) 
    {
    
    
        vector<int> vec;
        Traversal(root,vec);
        return vec;
    }
};

3.后序遍历

题目 难度:简单

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    void Traversal(TreeNode *cur,vector<int> &vec)
    {
    
    
        if(cur==nullptr)
        {
    
    
            return;//相当于中断
        }
        Traversal(cur->left,vec);
        Traversal(cur->right,vec);
        vec.push_back(cur->val);
    }
    vector<int> postorderTraversal(TreeNode* root) 
    {
    
    
        vector<int> vec;
        Traversal(root,vec);
        return vec;
    }
};

二叉树之统一迭代遍历

1.前序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 * */

class Solution {
    
    
public:
    vector<int> result;
    stack<TreeNode*> sta;
    vector<int> inorderTraversal(TreeNode* root)    
    {
    
    
    	if (root != nullptr) sta.push(root);
       
        while(!sta.empty())
        {
    
    
            TreeNode *cur=sta.top();
            
            if(cur!=nullptr)
            {
    
    
                sta.pop();//先把根结点弹出,防止重复
                 if(cur->right!=nullptr)
                {
    
    
                	sta.push(cur->right);//右
                }
				 if(cur->left!=nullptr)
                {
    
    
                	sta.push(cur->left);//左
                }
                 sta.push(cur);//中
                sta.push(nullptr);
            
            }
            else
            {
    
    
                sta.pop();
                result.push_back(sta.top()->val);
                sta.pop();
            }
        }
        return result;
    }
};

2.中序遍历

大致可以分为如下四部曲。

  1. root压入栈顶。

  2. 将栈顶节点取出,记为cur

  3. 判断:栈顶第一个非空节点 是否被视作根节点处理过?(cur是否为null?)

  4. 如否:进行处理
    将当前节点cur作为根节点。
    为使出栈时符合左-根-右的顺序,以右-根-左的顺序将节点入栈,具体如下:
    (1)将当前节点cur视作根节点,先出栈,以便后续操作
    (2)如有右节点则入栈,无则不入
    (3)当前节点cur入栈
    (4)将空指针nullptr入栈,标志cur已被处理过。同时,如无左节点,结束处理流程。
    (5)如有左节点,则左节点进入栈顶,结束处理流程。
    注:(2)、(5)确保栈顶始终是cur节点的左节点(若无左节点则为nullptr)。
    将重复此步处理,直到cur的左节点为空。此时,cur为下一个应加入result的节点。

  5. 如是:则该节点无左子树,或是左子树已被访问完毕。无论如何,现在,该节点应被加入result。
    (1)将当前节点cur加入result。
    (2)弹出栈顶的cur,以表示此节点已被加入result,无需再次被考虑。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 * */

class Solution {
    
    
public:
    vector<int> result;
    stack<TreeNode*> sta;
    vector<int> inorderTraversal(TreeNode* root)    
    {
    
    
    	if (root != nullptr) sta.push(root);
       
        while(!sta.empty())
        {
    
    
            TreeNode *cur=sta.top();
            
            if(cur!=nullptr)
            {
    
    
                sta.pop();//先把根结点弹出,防止重复
                if(cur->right!=nullptr)
                {
    
    
                	sta.push(cur->right);//右
                }

                sta.push(cur);//中
                sta.push(nullptr);
                if(cur->left!=nullptr)
                {
    
    
                	sta.push(cur->left);//左
                }
            }
            else
            {
    
    
                sta.pop();
                result.push_back(sta.top()->val);
                sta.pop();
            }
        }
        return result;
    }
};

3.后序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

class Solution {
    
    
public:
    vector<int> result;
    stack<TreeNode*> sta;
    vector<int> postorderTraversal(TreeNode* root) 
    {
    
    
        if (root != nullptr) sta.push(root);
        
        while(!sta.empty())
        {
    
    
            TreeNode *cur=sta.top();
            if(cur!=nullptr)
            {
    
    
                sta.pop();

                sta.push(cur);
                sta.push(nullptr);

                if(cur->right!=nullptr)
                {
    
    
                    sta.push(cur->right);
                }
                if(cur->left!=nullptr)
                {
    
    
                    sta.push(cur->left);
                }
                
            }
            else
            {
    
    
                sta.pop();
                result.push_back(sta.top()->val);
                sta.pop();
            }
        }
        return result;
    }
};

二叉树之层序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
    
    
        queue<TreeNode*> que;
        
        vector<vector<int>> result;

        if(root!=NULL)
        {
    
    
            que.push(root);
        }

        while(!que.empty())
        {
    
    
            vector<int> vec;
            //vec要放在这里定义,如果放在while外面定义,这样他的生存期就在这个函数里面。
            //等到下次调用这个while函数就可以得到一个空的vec;
            int size=que.size();//本层节点的个数

            while(size--)
            {
    
    
                TreeNode *node=que.front();
                
                vec.push_back(node->val);
                que.pop();
                
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
                
            }
            result.push_back(vec);
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/mabaizi/article/details/128758131