二叉树的遍历(三种遍历方式,前中后序;递归,栈,迭代实现)

遍历方式

良心推荐学习视频(前置知识)

1.球球大家去看啦,看过包会!!完美地讲解二叉树的前中后序遍历顺序,为后续的算法实现打下基础

2.二叉树非递归式遍历算法

3.二叉树的先序递归遍历算法--递归过程讲得非常详细!!!

4.二叉树的中后续遍历算法

小声bb ... 一遍看不懂就多看几次

递归遍历

递归递归,要递也要归(递归出口),只递不归就是耍流氓!!!
递归与迭代的时间复杂度差不多,但在空间复杂度上递归还要用栈存储参数返回值,有可能会造成栈溢出.

迭代遍历

重点:递归的深层原理就是利用栈

其实这里也有前置知识:

1.,要明白栈FILO(先进后出)的原理, 明白pop(),top(),push(),empty()可以执行什么操作

2.使用c/c++ 进行遍历时有可能会用到箭头表达式 '->'

请记住: 声明 int*p;

    (*p).val == p->val

记忆:箭头运算符左侧的变量类型一定是指针型

3.push_back()方法是vector的方法,用于向向量尾部添加元素

reverse(a.begin(),a.end())方法,用来反转容器

LeetCode---遍历二叉树

二叉树的遍历具体实现代码可能每个地方讲得不一样,但核心思想是一样的,所以最重要的是要理解,理解完了也要硬性记忆下,不然学得多了以后会忘掉.

ps.LeetCode已经把常用的STL标准库函数和数据结构都提前导入了,比如本题中的stack和vector都可以直接用.

1.前序遍历

题目:给你二叉树的根节点 root ,返回它节点值的 前序 遍历

输入:root = [1,null,2,3]

输出:[1,2,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>ans;//将preorderTraversal函数的返回值保存在vector容器中
    vector<int> preorderTraversal(TreeNode* root) {
        if(root)
        {
            ans.push_back(root->val);//根节点的值
            preorderTraversal(root->left);
            preorderTraversal(root->right);
        }
        return ans;

       
    }
};

/**使用栈遍历
 * 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>ans;
    vector<int> preorderTraversal(TreeNode* root) {
       stack<TreeNode*>st;
       TreeNode *p = root;//传参
       while(p || !st.empty())//p一直指向每一次的根节点
       {
           if(p)//根节点非空
           {
               ans.push_back(p->val);
               st.push(p);
               p = p->left;
           }
           else{//左子树访问完毕,开始访问右子树
               p = st.top();//获取栈顶元素
               st.pop();//弹栈
               p = p->right;

           }
       }
       return ans;

       
    }
};
/**迭代法
 * 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>ans;
    vector<int> preorderTraversal(TreeNode* root) {
       stack<TreeNode*>st;
       //TreeNode *p = root;//传参
       if(root)st.push(root);
       while(!st.empty())
       {
           TreeNode*node = st.top();
           if(node!=nullptr)
           {
               st.pop();
               if(node->right)st.push(node->right);//右
               if(node->left)st.push(node->left);//左
               st.push(node);//中
               st.push(nullptr);

           }
           else
           {
               st.pop();
               node = st.top();
               st.pop();
               ans.push_back(node->val);
           }
       }
       return ans;

       
    }
};

2.中序遍历

题目: 给定一个二叉树的根节点 root ,返回它的 中序 遍历。

输入:root = [1,null,2,3]

输出:[1,3,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:
    vector<int>ans;
    vector<int> inorderTraversal(TreeNode* root) {
        if(root)
        {
            inorderTraversal(root->left);
            ans.push_back(root->val);//根节点
            inorderTraversal(root->right);
        }
        return ans;
        
    }
};

/**栈的迭代
 * 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> inorderTraversal(TreeNode* root) {
        vector<int>ans;
        stack<TreeNode*>st;
        TreeNode* p = root;
        while( p!=nullptr|| !st.empty())
        {
            if(p!=nullptr)
            {
                st.push(p);
                p = p->left;
            }
            else{
                    p = st.top();
                    st.pop();
                    ans.push_back(p->val);
                    p = p->right;
                }
         
        }
        return ans;
        
        

    }
};

/**迭代法
 * 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>ans;
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*>st;
        if(root !=nullptr) st.push(root);//如果根节点非空,则将根节点入栈
        while(!st.empty())//若栈非空
        {
            TreeNode*node = st.top();node指向栈顶元素
            if(node != nullptr)//若栈顶元素非空
            {
                st.pop();//弹出栈顶元素
                if(node->right)st.push(node->right);//如果栈顶元素存在右孩子,则将右孩子入栈
                st.push(node);//右孩子入栈后,再重新将栈顶元素压入栈内
                st.push(nullptr);//向栈中压入一个空节点
                if(node->left)st.push(node->left);//如果根节点有左孩子,将左孩子入栈
            }else//如果栈顶元素为空--对应if语句块中的st.push(nullptr);步骤
            {
                st.pop();//弹出栈顶的nullptr
                node = st.top();//将栈顶指针指向根节点
                st.pop();//弹出新的栈顶元素(根节点)
                ans.push_back(node->val);//将根节点的值存入结果向量中
            }
        }
        return ans;//二叉树全部遍历完毕后返回结果向量
        
        

    }
};

后序遍历

题目:给定一个二叉树,返回它的后序遍历。

示例:

输入: [1,null,2,3]

输出: [3,2,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>ans;
    vector<int> postorderTraversal(TreeNode* root) {
        if(root)
        {
            postorderTraversal(root->left);
            postorderTraversal(root->right);
            ans.push_back(root->val);
        }
        return ans;
    }
};
/**利用栈遍历
 * 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>ans;
    vector<int> postorderTraversal(TreeNode* root) {
       stack<TreeNode*>st;
       st.push(root);
       TreeNode*p = root;
       st.push(p);
       while(!st.empty()||p!=nullptr)
       {
           if(p)
           {
                p = st.top();
                st.pop();
                ans.push_back(p->val);
           }
           else
           {
                st.push(p->left);
                st.push(p->right);
           }
       }
       reverse(ans.begin(),ans.end());//将结果翻转
       return ans;
    }
};
/**迭代法
 * 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>ans;
    vector<int> postorderTraversal(TreeNode* root) {
       stack<TreeNode*>st;
       if(root !=nullptr)
       {
           st.push(root);
       } 
       while(!st.empty())
       {
           TreeNode* node = st.top();
           if(node!=nullptr)
           {
               st.pop();
               st.push(node);//中
               st.push(nullptr);
               if(node->right)st.push(node->right);//右
               if(node->left)st.push(node->left);//左
           }
           else
           {
               st.pop();
               node = st.top();
               st.pop();
               ans.push_back(node->val);
           }
       }
       return ans;
    }
};

posted @ 2020-11-21 17:09  顾小朝  阅读(654)  评论(0编辑  收藏  举报