力扣 二叉树的层序遍历-102

news2024/11/28 21:39:19

二叉树的层序遍历-102

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res; // 二维数组用来存储每层节点
        if (root == nullptr)
            return res;
        queue<TreeNode*> q; // 队列用来进行层序遍历
        q.push(root);       // 将第一层的根节点加入队列中
        while (!q.empty()) {
            int n = q.size(); // 当前层的节点个数
            vector<int> vec;  // 用于存储当前层的所有节点
            for (int i = 1; i <= n; i++) {//遍历当前层的所有节点
                TreeNode* node = q.front();//将队列当前节点存下来
                q.pop();//将当前节点弹出队列
                vec.push_back(node->val);//将存下来的当前节点
                if (node->left)q.push(node->left);//如果当前节点有左节点,加入队列
                if (node->right)q.push(node->right);//如果当前节点有右节点,加入队列
            }
            res.push_back(vec);//将当前层的节点值加入结果
        }
        return res;
    }
};

什么是 C++ 中的函数对象?它有什么特点?函数对象与普通函数有什么区别? 如何定义和使用函数对象?

C++ 中的函数对象(Function Object)

函数对象(又称为函数符号)是一个可以像普通函数一样被调用的对象。在 C++ 中,函数对象是通过重载 operator() 来实现的。它的本质上是一个类的实例,而该类的实例具有函数调用的能力。因此,函数对象可以像普通函数一样在代码中传递和调用。

函数对象的特点

1.像函数一样调用:

        函数对象是通过重载 operator() 来实现的,它使得该对象能够像函数一样被调用。

2.可以有状态:

        函数对象与普通函数的最大区别是,函数对象可以拥有成员变量(即状态)。这使得它在多次调用时可以保持和修改状态。

3.可以传递给算法:

        函数对象可以作为参数传递给 C++ 标准库中的算法(如 std::sort、std::for_each 等),并且由于它们是对象,可以在调用时携带更多的上下文信息。

4.性能:

        函数对象通常可以通过内联优化,从而提高性能,特别是与普通函数指针相比,它们能更好地支持编译器优化。

5.支持多态:

        函数对象可以通过继承和多态进行扩展,支持不同的行为和策略模式。

函数对象与普通函数的区别

如何定义和使用函数对象

1. 定义函数对象

要定义一个函数对象,需要:

        创建一个类。

        在类中重载 operator() 方法,使对象能够像函数一样调用。

#include <iostream>
using namespace std;

// 定义一个函数对象
class Add {
public:
    int operator()(int x, int y) {
        return x + y;  // 重载 operator() 实现加法操作
    }
};

int main() {
    Add add;  // 创建函数对象
    cout << add(2, 3) << endl;  // 调用函数对象,相当于调用 add.operator()(2, 3)
    return 0;
}

输出:

5

2. 使用函数对象作为参数

函数对象可以作为参数传递给 C++ 标准库中的算法,像是 std::for_each、std::sort 等。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 函数对象:加法操作
class Add {
public:
    void operator()(int x) {
        cout << x + 10 << " ";  // 每个元素加 10
    }
};

int main() {
    vector<int> nums = {1, 2, 3, 4, 5};
    
    // 使用函数对象作为参数
    for_each(nums.begin(), nums.end(), Add());
    
    return 0;
}

输出:

11 12 13 14 15

3. 函数对象作为排序准则

函数对象也可以用于自定义排序准则,比如与 std::sort 一起使用:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 函数对象:比较两个整数的大小
class Compare {
public:
    bool operator()(int x, int y) {
        return x > y;  // 降序排列
    }
};

int main() {
    vector<int> nums = {5, 1, 8, 3, 7};
    
    // 使用函数对象作为排序准则
    sort(nums.begin(), nums.end(), Compare());

    // 打印排序后的结果
    for (int num : nums) {
        cout << num << " ";
    }

    return 0;
}

输出:

8 7 5 3 1

4. 函数对象的带状态

函数对象不仅仅能执行操作,还可以保存一些状态,下一次调用时可以利用这些状态。

#include <iostream>

using namespace std;

// 函数对象:加法器,带状态
class Adder {
private:
    int sum = 0;  // 存储状态

public:
    void operator()(int x) {
        sum += x;  // 修改状态
        cout << "Current sum: " << sum << endl;
    }
};

int main() {
    Adder add;
    add(10);  // sum = 10
    add(20);  // sum = 30
    add(30);  // sum = 60
    return 0;
}

输出:

Current sum: 10
Current sum: 30
Current sum: 60

在这个例子中,Adder 类通过一个成员变量 sum 来保存当前的总和,每次调用 operator() 时都会修改这个状态。

函数对象的应用场景

1.算法:

        C++ 标准库中有很多算法(如 std::for_each, std::sort, std::transform 等)都可以使用函数对象进行定制化操作。例如,使用函数对象作为排序准则,或者用作算法中的自定义操作。

2.回调机制:

        函数对象可以用来实现回调机制,它们的状态可以保存更多上下文信息,因此比普通函数更灵活。

3.自定义操作:

        需要在运行时根据某些条件定制化操作时,函数对象比普通函数更加灵活。通过在类中保存状态和行为,函数对象可以实现更复杂的行为。

总结

        函数对象 是可以像普通函数一样被调用的类实例,通过重载 operator() 来实现。

        函数对象的优势:除了能像普通函数一样调用,它们还能拥有状态,并且能够灵活扩展,使得代码更具可读性和可扩展性。

        与普通函数的区别:函数对象不仅可以像普通函数一样执行操作,还能够保存和改变状态,支持多态性和灵活性。

        应用:函数对象广泛应用于 C++ 标准库算法(如排序、遍历等)中,能够提供定制化的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙学习使用本地真机运行应用/元服务 (开发篇)

文章目录 1、前提条件2、使用USB连接方式3、使用无线调试连接方式4、运行 1、前提条件 在Phone和Tablet中运行HarmonyOS应用/元服务的操作方法一致&#xff0c;可以采用USB连接方式或者无线调试的连接方式。两种连接方式是互斥的&#xff0c;只能使用一种&#xff0c;无法同时…

数据库导论

data 数据是数据库中存储的基本数据&#xff0c;描述事物的符号称为数据。 DB 数据库是长期存储在计算机内&#xff0c;有组织&#xff0c;可共享的大量数据的集合。数据库中的数据按照一定的数据模型组织&#xff0c;描述和存储&#xff0c;具有较小的冗余度&#xff0c;较…

数据结构 ——— 归并排序算法的实现

目录 归并排序的思想 归并排序算法的实现 归并排序的思想 将已经有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序后&#xff0c;再使子序列段间有序 若将两个有序表合并成一个有序表&#xff0c;称为二路归并 归并排序步骤示意图&#x…

【数据结构】【线性表】一文讲完队列(附C语言源码)

队列 队列的基本概念基本术语基本操作 队列的顺序实现顺序队列结构体的创建顺序队列的初始化顺序队列入队顺序队列出队顺序队列存在的问题分析循环队列代码汇总 队列的链式实现链式队列的创建链式队列初始化-不带头结点链式队列入队-不带头节点链式队列出队-不带头结点带头结点…

chrome允许http网站打开摄像头和麦克风

第一步 chrome://flags/#unsafely-treat-insecure-origin-as-secure 第二步 填入网址&#xff0c;点击启用 第三步 重启 Chrome&#xff1a;设置完成后&#xff0c;点击页面底部的 “Relaunch” 按钮&#xff0c;重新启动 Chrome 浏览器&#xff0c;使更改生效。

Spring Boot教程之十: 使用 Spring Boot 实现从数据库动态下拉列表

使用 Spring Boot 实现从数据库动态下拉列表 动态下拉列表&#xff08;或依赖下拉列表&#xff09;的概念令人兴奋&#xff0c;但编写起来却颇具挑战性。动态下拉列表意味着一个下拉列表中的值依赖于前一个下拉列表中选择的值。一个简单的例子是三个下拉框&#xff0c;分别显示…

DRM(数字权限管理技术)防截屏录屏----视频转hls流加密、web解密播放

提示&#xff1a;视频转hls流加密、web解密播放 需求&#xff1a;研究视频截屏时&#xff0c;播放器变黑&#xff0c;所以先研究的视频转hls流加密 文章目录 [TOC](文章目录) 前言一、工具ffmpeg、openssl二、后端nodeexpress三、web播放四、文档总结 前言 ‌HLS流媒体协议‌&a…

视觉经典神经网络与复现:深入解析与实践指南

目录 引言 经典视觉神经网络模型详解 1. LeNet-5&#xff1a;卷积神经网络的先驱 LeNet-5的关键特点&#xff1a; 2. AlexNet&#xff1a;深度学习的突破 AlexNet的关键特点&#xff1a; 3. VGGNet&#xff1a;深度与简洁的平衡 VGGNet的关键特点&#xff1a; 4. ResNe…

【算法day1】数组:双指针算法

题目引用 这里以 1、LeetCode704.二分查找 2、LeetCode27.移除元素 3、LeetCode977.有序数组的平方 这三道题举例来说明数组中双指针的妙用。 1、二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜…

华为云云连接+squid进行正向代理上网冲浪

1 概述 ‌Squid‌是一个高性能的代理缓存服务器&#xff0c;主要用于缓冲Internet数据。它支持多种协议&#xff0c;包括FTP、gopher、HTTPS和HTTP。Squid通过一个单独的、非模块化的、I/O驱动的进程来处理所有的客户端请求&#xff0c;这使得它在处理请求时具有较高的效率‌。…

2024年11月24日Github流行趋势

项目名称&#xff1a;FreeCAD 项目维护者&#xff1a;wwmayer, yorikvanhavre, berndhahnebach, chennes, WandererFan等项目介绍&#xff1a;FreeCAD是一个免费且开源的多平台3D参数化建模工具。项目star数&#xff1a;20,875项目fork数&#xff1a;4,117 项目名称&#xff1…

二叉树:堆的建立和应用

在建立堆之前&#xff0c;我们要知道什么是树和二叉树 树 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个结点组成的一个具有层次关系的集合&#xff0c;之所以把它叫做树&#xff0c;是因为它长得像一棵倒挂的树&#xff0c;也就是根在上面&…

使用 pycharm 新建不使用 python 虚拟环境( venv、conda )的工程

有时候我们发现一个好玩的 demo&#xff0c;想赶快在电脑上 pip install 一下跑起来&#xff0c;发现因为 python 的 venv、conda 环境还挺费劲的&#xff0c;因为随着时间的发展&#xff0c;之前记得很清楚的 venv、conda 的用法&#xff0c;不经常使用&#xff0c;半天跑不起…

(详细文档!)java swing学生信息管理系统 +mysql

第一章&#xff1a;系统功能分析 1.1、系统简介与开发背景 学生信息管理系统是在信息化时代&#xff0c;特别是在教育领域中产生的。随着学校规模的不断扩大和信息化技术的不断发展&#xff0c;传统的纸质档案管理方式已经无法满足学校对学生信息管理的需求&#xff0c;因此需…

租辆酷车小程序开发(二)—— 接入微服务GRPC

vscode中golang的配置 设置依赖管理 go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct GO111MODULEauto 在$GOPATH/src 外面且根目录有go.mod 文件时&#xff0c;开启模块支持 GO111MODULEoff 无模块支持&#xff0c;go会从GOPATH 和 vendor 文件夹寻找包…

集合卡尔曼滤波(EnKF)的三维滤波(模拟平面定位)例程,带逐行注释

这段 MATLAB 代码实现了一个三维动态系统的集合卡尔曼滤波&#xff08;Ensemble Kalman Filter, EnKF&#xff09;示例。代码的主要目的是通过模拟真实状态和测量值&#xff0c;使用 EnKF 方法对动态系统状态进行估计。 文章目录 参数设置初始化真实状态定义状态转移和测量矩阵…

鸿蒙千帆启新程,共绘数字生态蓝图

华为的鸿蒙千帆起计划&#xff1a;共筑数字未来&#xff0c;学习华为创新之路 在当今全球科技竞争日益激烈的背景下&#xff0c;华为作为中国科技企业的代表&#xff0c;正通过其自主创新的鸿蒙系统&#xff0c;引领一场移动应用生态的变革。鸿蒙千帆起计划&#xff0c;作为华…

python控制鼠标,键盘,adb

python控制鼠标&#xff0c;键盘&#xff0c;adb 听说某系因为奖学金互相举报&#xff0c;好像拿不到要命一样。不禁想到几天前老墨偷走丁胖子的狗&#xff0c;被丁胖子逮到。他面对警察的问询面不改色坚持自我&#xff0c;反而是怒气冲冲的丁胖子被警察认为是偷狗贼。我觉得这…

yum安装升级指定版本软件

与apt相同&#xff0c;yum也可以指定升级软件版本。 这里以升级gitlab-ce为例。 获得当前可用版本命令如下&#xff1a; yum list gitlab-ce --showduplicates 查看当前gitlab版本。在/var/opt/gitlab/gitlab-rails/查看VERSION文件内容&#xff1a; cat VERSION 当前版本…

el-table根据接口返回某一个字段合并行

根据名称相同合并行 <template><div><el-table :data"responseSearchIntegralAddData" :span-method"objectSpanMethod1" border style"width: 100%"><el-table-column prop"integralTypeName" label"名称…