栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

遍历二叉树的三种方法的六种实现

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

遍历二叉树的三种方法的六种实现

遍历二叉树的三种方法的六种实现

有详细(相对)的注释

文章目录
    • 遍历二叉树的三种方法的六种实现
      • (1)先序
      • (2)中序
      • (3)后序
      • (4)一种不同的迭代 层次遍历

(1)先序

力扣144.二叉树的前序遍历
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

递归:

class Solution
{
public:
    void dfs(TreeNode *root, vector &vec)
    {
        if (root != nullptr)
        {
            vec.push_back(root->val);
            dfs(root->left, vec);
            dfs(root->right, vec);
            return;
        }
        else
            return;
    }
    vector preorderTraversal(TreeNode *root)
    {
        vector re;
        dfs(root, re);
        return re;
    }
};

栈:
怎么用栈实现呢,可真的是把我难到了。
先序遍历的过程是,访问中间的节点,再访问他的左子树和右子树。左子树也是先根节点,再左左子树。
所以,先访问根节点,然后访问左子树,根节点进栈,出栈的时候取出他的右子树这样?
比如根节点出栈,就访问右节点(右子树的根节点),它进栈,访问左子树

class Solution {
public:

    vector preorderTraversal(TreeNode *root) {
        stack stk;
        vector re;
        TreeNode *now = nullptr;
        if (root != nullptr) {
            re.push_back(root->val);
            stk.push(root);
            now = root->left;
        }

        while (!stk.empty()) {
            if (now != nullptr) {
                re.push_back(now->val);
                stk.push(now);
                now = now->left;
            } else {
                //now是空指针,上一个出栈,访问右
                TreeNode *middle = stk.top(); //就是他左节点是空的
                stk.pop();

                TreeNode *right_node = middle->right;
                if (right_node != nullptr) {
                    re.push_back(right_node->val);
                    stk.push(right_node);
                    //现在 right_node是这颗右子树的middle
                    now = right_node->left;
                } else continue;  //右节点也是空的
            }
        }
        return re;
    }
};
(2)中序

递归:

class Solution {
public:
    void dfs(TreeNode* root, vector& re  ){
        if(root== nullptr) return;
        dfs(root->left, re) ;
        re.push_back(root->val);
        dfs(root->right, re);        
    }
    vector inorderTraversal(TreeNode* root) {
        vector re;        
        dfs(root, re);
        return re;
    }
};

循环:
就是把所有左节点都进栈。直到空指针就访问上一个左节点。

    vector inorderTraversal(TreeNode* root) {
        vector re;
        stackstk;
        auto now = root;
        while(stk.empty()==0 || now!= nullptr){
            if(now!= nullptr){  //这里可以用一个while遍历入栈左边一条链
                stk.push(now);
                now = now->left;
            } else {
                re.push_back(stk.top()->val);
                now = stk.top()->right;
                stk.pop();
            }
        }
        return re;
    }
(3)后序

递归:懒得写了
循环:遇到的问题是,出栈中间节点的时候,不知道右边有没有遍历过。【利用pre记录上一个访问过的结点 左节点】

class Solution {
public:
    vector postorderTraversal(TreeNode* root) {
        vectorre;
        stackstk;
        auto now = root;
        TreeNode* pre = nullptr;
        while(!stk.empty() || now!= nullptr ){
            while(now!= nullptr){
                stk.push(now);
                now = now->left;
            }
            auto middle = stk.top();
            stk.pop();
            if(middle->right== nullptr||pre==middle->right){
                re.push_back(middle->val);
                pre = middle;

            }else{
                now = middle->right;
                stk.push(middle);  //这里没想到
            }
        }
        return re;
   }
};
(4)一种不同的迭代 层次遍历

之前都是用的栈,这种用队列。

class Solution {
public:
    vector> levelOrder(TreeNode* root) {
        queuenodes;
        vector >re;
        if(!root) return re;
        nodes.push(root);
        while( !nodes.empty()){
            auto size = nodes.size();
            vector line;
            for(int i =1; i<=size; i++){  //这里没想到
                auto now = nodes.front(); nodes.pop();
                line.push_back(now->val);
                if(now->left) nodes.push(now->left);
                if(now->right) nodes.push(now->right);
            }            
            re.push_back(line);
        }
        return re;
    }
};
//ret.push_back(vector  ());
// ret.back().push_back(node->val);

学到一个C++vector这样插入一行的办法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/384976.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号