从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(下)

简介: 从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145

从C语言到C++_25(树的十道OJ题)力扣:606+102+107+236+426+105+106+144+94+145(中):https://developer.aliyun.com/article/1521950

144. 二叉树的前序遍历 - 力扣(LeetCode)

难度简单

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

示例 1:


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

输出:[1,2,3]


示例 2:

输入:root = []

输出:[]


示例 3:

输入:root = [1]

输出:[1]


示例 4:


输入:root = [1,2]

输出:[1,2]


示例 5:



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

输出:[1,2]


提示:

  • 树中节点数目在范围 [0, 100]
  • -100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

/**
 * 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> preorderTraversal(TreeNode* root) {
 
};

解析代码:

这道题用C语言写过递归版本的,当时说了后面会用非递归写,兑现承诺了属于是:

数据结构与算法⑮(第四章_下)二叉树OJ(力扣:144,965,104,110,226,100,101,572)_GR C的博客-CSDN博客

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty()) // 开始访问每一颗树,最后再写退出循环的条件
        {
            while(cur) // 1.左路结点的值直接输出,结点入栈
            {
                v.push_back(cur->val);
                st.push(cur);
                cur = cur->left;
            }
 
            TreeNode* top = st.top(); // 2.访问左路结点的右子树
            st.pop();
            cur = top->right; // 子问题回到循环访问右子树,非递归的精髓
        }
        return v;
    }
};

94. 二叉树的中序遍历 - 力扣(LeetCode)

难度简单

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

示例 1:


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

输出:[1,3,2]


示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [1]

输出:[1]


提示:

  • 树中节点数目在范围 [0, 100]
  • -100 <= Node.val <= 100

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

/**
 * 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) {
 
    }
};

解析代码:

上面也有其它思路,但我们上面的思路前中后序遍历的思路是互通的,只是输出时机不同

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        while(cur || !st.empty()) // 开始访问每一颗树
        {
            while(cur) // 1.左路结点入栈
            {
                st.push(cur);
                cur = cur->left;
            }
            // 当这个结点从栈出来,表明这个结点的左路结点已经访问了
            TreeNode* top = st.top();
            st.pop();
            v.push_back(top->val); // 2. 输出这个结点
            cur = top->right; // 子问题回到循环访问右子树,非递归的精髓
        }
        return v;
    }
};

145. 二叉树的后序遍历 - 力扣(LeetCode)

难度简单

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历

示例 1:


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

输出:[3,2,1]


示例 2:

输入:root = []

输出:[]


示例 3:

输入:root = [1]

输出:[1]


提示:

  • 树中节点的数目在范围 [0, 100]
  • -100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

/**
 * 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> postorderTraversal(TreeNode* root) {
 
    }
};

解析代码:

后序和前面两个有点不一样,当你左路结点访问了,这时如果你的右结点为空,

你可以输出根结点,否则要访问右结点,访问右结点之后,回到根结点,

根结点的右结点还是不为空,所以根结点的右结点访问过了的情况也要输出根结点:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> st;
        vector<int> v;
        TreeNode* cur = root;
        TreeNode* prev = nullptr;
        while(cur || !st.empty()) // 开始访问每一颗树
        {
            while(cur) // 1.左路结点入栈
            {
                st.push(cur);
                cur = cur->left;
            }
            // 当这个结点从栈出来,表明这个结点的左路结点已经访问了
            TreeNode* top = st.top();
            if(top->right == nullptr || prev == top->right) //如果右为空或者上一个输出的结点是右
            {
                v.push_back(top->val); // 2. 输出这个结点
                prev = top; // 记录上一个输出的结点
                st.pop();
            }
            else
            {
                cur = top->right; // 子问题回到循环访问右子树,非递归的精髓
            }
        }
        return v;
    }
};

本章完。

下一部分:set和map容器

目录
相关文章
|
4月前
|
安全 编译器 C语言
C++入门1——从C语言到C++的过渡
C++入门1——从C语言到C++的过渡
93 2
|
2月前
|
算法 编译器 C语言
【C语言】C++ 和 C 的优缺点是什么?
C 和 C++ 是两种强大的编程语言,各有其优缺点。C 语言以其高效性、底层控制和简洁性广泛应用于系统编程和嵌入式系统。C++ 在 C 语言的基础上引入了面向对象编程、模板编程和丰富的标准库,使其适合开发大型、复杂的软件系统。 在选择使用 C 还是 C++ 时,开发者需要根据项目的需求、语言的特性以及团队的技术栈来做出决策。无论是 C 语言还是 C++,了解其优缺点和适用场景能够帮助开发者在实际开发中做出更明智的选择,从而更好地应对挑战,实现项目目标。
123 0
|
4月前
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
109 10
|
4月前
|
程序员 C语言
【C语言】LeetCode(力扣)上经典题目
【C语言】LeetCode(力扣)上经典题目
|
5月前
|
算法 机器人 C语言
ROS仿真支持C++和C语言
ROS仿真支持C++和C语言
151 1
|
4月前
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
52 0
|
4天前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
1天前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
1天前
|
安全 编译器 C语言
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
|
1天前
|
存储 程序员 C语言
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。

热门文章

最新文章