算法沉淀——二叉树中的深搜(leetcode真题剖析)

news2024/12/23 3:45:05

在这里插入图片描述

算法沉淀——二叉树中的深搜

  • 01.计算布尔二叉树的值
  • 02.求根节点到叶节点数字之和
  • 03.二叉树剪枝
  • 04.验证二叉搜索树
  • 05.二叉搜索树中第K小的元素
  • 06.二叉树的所有路径

二叉树的深度优先搜索是一种遍历二叉树的方法,它通过深度递归的方式探索树的结构。有两种主要形式:前序遍历、中序遍历、和后序遍历。在二叉树上执行深度优先搜索,意味着首先探索到树的深度,然后回溯到更浅的层次。

以下是三种常见的二叉树深度优先搜索方式的定义:

  1. 前序遍历(Preorder Traversal)

    • 访问根节点
    • 递归地前序遍历左子树
    • 递归地前序遍历右子树
    根 -> 左子树 -> 右子树
    
  2. 中序遍历(Inorder Traversal)

    • 递归地中序遍历左子树
    • 访问根节点
    • 递归地中序遍历右子树
    左子树 -> 根 -> 右子树
    
  3. 后序遍历(Postorder Traversal)

    • 递归地后序遍历左子树
    • 递归地后序遍历右子树
    • 访问根节点
    左子树 -> 右子树 -> 根
    

在实现深度优先搜索时,通常使用递归的方法,递归函数的调用栈会自动帮助我们在深度上进行探索。对于每个节点,首先处理当前节点,然后递归处理其左子树和右子树。

示例代码(C++):

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

void preorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    // 处理当前节点
    cout << root->val << " ";
    // 递归处理左子树
    preorderTraversal(root->left);
    // 递归处理右子树
    preorderTraversal(root->right);
}

void inorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    // 递归处理左子树
    inorderTraversal(root->left);
    // 处理当前节点
    cout << root->val << " ";
    // 递归处理右子树
    inorderTraversal(root->right);
}

void postorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    // 递归处理左子树
    postorderTraversal(root->left);
    // 递归处理右子树
    postorderTraversal(root->right);
    // 处理当前节点
    cout << root->val << " ";
}

这些函数分别实现了二叉树的前序、中序和后序深度优先搜索。在实际应用中,可以根据问题的要求选择不同的遍历方式。

01.计算布尔二叉树的值

题目链接:https://leetcode.cn/problems/evaluate-boolean-binary-tree/

给你一棵 完整二叉树 的根,这棵树有以下特征:

  • 叶子节点 要么值为 0 要么值为 1 ,其中 0 表示 False1 表示 True
  • 非叶子节点 要么值为 2 要么值为 3 ,其中 2 表示逻辑或 OR3 表示逻辑与 AND

计算 一个节点的值方式如下:

  • 如果节点是个叶子节点,那么节点的 为它本身,即 True 或者 False
  • 否则,计算 两个孩子的节点值,然后将该节点的运算符对两个孩子值进行 运算

返回根节点 root 的布尔运算值。

完整二叉树 是每个节点有 0 个或者 2 个孩子的二叉树。

叶子节点 是没有孩子的节点。

示例 1:

输入:root = [2,1,3,null,null,0,1]
输出:true
解释:上图展示了计算过程。
AND 与运算节点的值为 False AND True = False 。
OR 运算节点的值为 True OR False = True 。
根节点的值为 True ,所以我们返回 true 。

示例 2:

输入:root = [0]
输出:false
解释:根节点是叶子节点,且值为 false,所以我们返回 false 。

提示:

  • 树中节点数目在 [1, 1000] 之间。
  • 0 <= Node.val <= 3
  • 每个节点的孩子数为 02
  • 叶子节点的值为 01
  • 非叶子节点的值为 23

思路

二叉树的大部分题目都可划分为子问题,所以一般我们都使用递归来解决,这里我们要先访问左右节点再访问根节点进行运算,所以这里使用的应该是后序遍历来写递归函数。

代码

class Solution {
public:
    bool evaluateTree(TreeNode* root) {
        if(!root->left) return root->val;

        int left = evaluateTree(root->left);
        int right = evaluateTree(root->right);

        return root->val==2?left|right:left&right;
    }
};

02.求根节点到叶节点数字之和

题目链接:https://leetcode.cn/problems/sum-root-to-leaf-numbers/

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 09 之间的数字。

每条从根节点到叶节点的路径都代表一个数字:

  • 例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123

计算从根节点到叶节点生成的 所有数字之和

叶节点 是指没有子节点的节点。

示例 1:

输入:root = [1,2,3]
输出:25
解释:
从根到叶子节点路径 1->2 代表数字 12
从根到叶子节点路径 1->3 代表数字 13
因此,数字总和 = 12 + 13 = 25

示例 2:

输入:root = [4,9,0,5,1]
输出:1026
解释:
从根到叶子节点路径 4->9->5 代表数字 495
从根到叶子节点路径 4->9->1 代表数字 491
从根到叶子节点路径 4->0 代表数字 40
因此,数字总和 = 495 + 491 + 40 = 1026 

提示:

  • 树中节点的数目在范围 [1, 1000]
  • 0 <= Node.val <= 9
  • 树的深度不超过 10

思路

在前序遍历过程中,我们能够通过向左右子树传递信息,并在回溯时获取左右子树的返回值。递归函数的作用主要体现在两个方面:

  1. 整合父节点的数字与当前节点的信息,计算出当前节点的数字,并将其传递到下一层进行递归;
  2. 当遇到叶子节点时,停止向下传递信息,而是将整合的结果一直回溯到根节点。递归结束时,根节点需要返回的值即为整棵树的数字和。

代码

class Solution {
public:
    int sumNumbers(TreeNode* root) {
        return dfs(root,0);
    }

    int dfs(TreeNode* root,int pre){
        int presum = pre*10+root->val;

        if(!root->left&&!root->right) return presum;

        int ret=0;
        if(root->left) ret+=dfs(root->left,presum);
        if(root->right) ret+=dfs(root->right,presum);

        return ret;
    }
};
  1. int sumNumbers(TreeNode* root): 这是主要的函数,用于计算二叉树中所有从根节点到叶子节点的路径和。它调用了辅助函数dfs,并将初始的前缀和设为0。
  2. int dfs(TreeNode* root, int pre): 这是递归的辅助函数,用于深度优先搜索计算路径和。它接收当前节点和前一个节点的路径和,然后计算当前节点的路径和。
    • int presum = pre * 10 + root->val;: 计算当前节点的路径和,乘以10表示将前一个节点的值左移一位,然后加上当前节点的值。
    • if (!root->left && !root->right) return presum;: 如果当前节点是叶子节点,直接返回当前节点的路径和,表示找到了一条完整的路径。
    • int ret = 0;: 初始化一个变量ret,用于累加左子树和右子树的路径和。
    • if (root->left) ret += dfs(root->left, presum);: 如果左子树存在,递归计算左子树的路径和,并累加到ret中。
    • if (root->right) ret += dfs(root->right, presum);: 如果右子树存在,递归计算右子树的路径和,并累加到ret中。
    • return ret;: 返回累加的结果,表示以当前节点为起点的所有路径和。

03.二叉树剪枝

题目链接:https://leetcode.cn/problems/binary-tree-pruning/

给你二叉树的根结点 root ,此外树的每个结点的值要么是 0 ,要么是 1

返回移除了所有不包含 1 的子树的原二叉树。

节点 node 的子树为 node 本身加上所有 node 的后代。

示例 1:

输入:root = [1,null,0,0,1]
输出:[1,null,0,null,1]
解释:
只有红色节点满足条件“所有不包含 1 的子树”。 右图为返回的答案。

示例 2:

输入:root = [1,0,1,0,0,0,1]
输出:[1,null,1,null,1]

示例 3:

输入:root = [1,1,0,1,1,0,1,0]
输出:[1,1,0,1,1,null,1]

提示:

  • 树中节点的数目在范围 [1, 200]
  • Node.val01

思路

这里我们可以通过题目可以,我们要先考虑左右子树才能判断当前节点是否能够删除,所以这里我们采用后序遍历方式来使用递归解决此问题

代码

class Solution {
public:
    TreeNode* pruneTree(TreeNode* root) {
        if(!root) return nullptr;

        root->left=pruneTree(root->left);
        root->right=pruneTree(root->right);

        if(!root->left&&!root->right&&root->val==0){
            delete root;
            root=nullptr;
        }

        return root;
    }
};
  1. TreeNode* pruneTree(TreeNode* root): 这是主要的函数,用于修剪二叉树。它通过递归调用pruneTree函数来修剪左子树和右子树,并在修剪后检查当前节点是否需要删除。
  2. if (!root) return nullptr;: 如果当前节点为空,直接返回nullptr,表示空节点。
  3. root->left = pruneTree(root->left);root->right = pruneTree(root->right);: 递归调用pruneTree函数,分别修剪左子树和右子树。
  4. if (!root->left && !root->right && root->val == 0) {: 如果当前节点是叶子节点且值为0,表示可以删除该节点。
    • delete root;: 释放当前节点的内存。
    • root = nullptr;: 将当前节点指针置为空,确保不再指向已删除的节点。
  5. return root;: 返回修剪后的当前节点,包括修剪后的左子树和右子树。

04.验证二叉搜索树

题目链接:https://leetcode.cn/problems/validate-binary-search-tree/

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入:root = [2,1,3]
输出:true

示例 2:

输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。

提示:

  • 树中节点数目范围在[1, 104]
  • -231 <= Node.val <= 231 - 1

思路

这里我们可以采用二叉搜索树的一个性质,即中序遍历后为一个有序序列,所以我们只需要中序遍历二叉树时判断当前节点是否比前一个节点大即可,在遍历左子树和当前节点时,不符合直接返回false可以剪去不必要遍历的枝。

代码

class Solution {
    long prev=LONG_MIN;
public:
    bool isValidBST(TreeNode* root) {
        if(!root) return true;
        bool left = isValidBST(root->left);
        if(!left) return false;

        bool cur=false;
        if(root->val>prev) cur=true;
        if(!cur) return false;

        prev=root->val;
        bool right =isValidBST(root->right);

        return left&&right&&cur;
    }
};
  1. long prev = LONG_MIN;: 这个类成员变量用于追踪上一个访问的节点的值,初始值设置为LONG_MIN,即负无穷,以确保对根节点的验证不会出现问题。

  2. bool isValidBST(TreeNode* root): 这是主要的函数,用于验证二叉搜索树是否合法。

    • if (!root) return true;: 如果当前节点为空,表示是合法的BST,直接返回true
    • bool left = isValidBST(root->left);: 递归验证左子树是否合法。
    • if (!left) return false;: 如果左子树不合法,直接返回false,因为整个树已经不合法了。
    • bool cur = false;: 初始化一个变量cur,用于表示当前节点是否满足BST的条件。
    • if (root->val > prev) cur = true;: 如果当前节点的值大于上一个节点的值,说明当前节点满足BST的条件。
    • if (!cur) return false;: 如果当前节点不满足BST的条件,直接返回false
    • prev = root->val;: 更新prev为当前节点的值,以备下次验证使用。
    • bool right = isValidBST(root->right);: 递归验证右子树是否合法。
    • return left && right && cur;: 返回左子树、右子树和当前节点是否都满足BST的条件。

05.二叉搜索树中第K小的元素

题目链接:https://leetcode.cn/problems/kth-smallest-element-in-a-bst/

给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。

示例 1:

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

示例 2:

输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3 

提示:

  • 树中的节点数为 n
  • 1 <= k <= n <= 104
  • 0 <= Node.val <= 104

**进阶:**如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

思路

根据上面的题目我们不难想到使用中序遍历和计数的方式来找到第k小的值,并加上计数器的剪枝优化。

代码

class Solution {
    int count,ret;
public:
    int kthSmallest(TreeNode* root, int k) {
        count=k;
        dfs(root);
        return ret;
    }

    void dfs(TreeNode* root){
        if(root==nullptr||!count) return;

        dfs(root->left);
        count--;
        if(!count) ret=root->val;
        dfs(root->right);
    }
};
  1. int count, ret;: 这两个类成员变量用于追踪当前要找的第 k 小的元素的数量(count)和最终找到的结果(ret)。
  2. int kthSmallest(TreeNode* root, int k): 这是主要的函数,用于调用 DFS 函数并返回结果。首先将 count 初始化为 k,然后调用 dfs(root)
  3. void dfs(TreeNode* root): 这是深度优先搜索(DFS)函数,用于在二叉搜索树中找到第 k 小的元素。
    • if (root == nullptr || !count) return;: 如果当前节点为空或者已经找到了第 k 小的元素,直接返回。
    • dfs(root->left);: 递归调用 DFS 函数,遍历左子树。
    • count--;: 每次访问一个节点,将 count 减一,表示已经找到了一个较小的元素。
    • if (!count) ret = root->val;: 如果 count 变为零,表示找到了第 k 小的元素,将结果记录在 ret 中。
    • dfs(root->right);: 递归调用 DFS 函数,遍历右子树。
  4. return ret;: 返回最终找到的第 k 小的元素。

06.二叉树的所有路径

题目链接:https://leetcode.cn/problems/binary-tree-paths/

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]

示例 2:

输入:root = [1]
输出:["1"] 

提示:

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

思路

使用深度优先遍历(DFS)来解决问题。路径以字符串形式存储,从根节点开始遍历,每次遍历时将当前节点的值加入到路径中。如果该节点为叶子节点,将路径存储到结果中。否则,将"->"加入到路径中并递归遍历该节点的左右子树。定义一个结果数组,在递归过程中进行路径的构建和存储。具体递归实现方法如下:

  1. 如果当前节点不为空,则将当前节点的值加入路径 path 中,否则直接返回;
  2. 判断当前节点是否为叶子节点,如果是,则将当前路径加入到所有路径的存储数组 ret 中;
  3. 否则,将当前节点值加上"->"作为路径的分隔符,继续递归遍历当前节点的左右子节点;
  4. 返回结果数组。

需要注意的是这里我们传入path时,不传引用,否则回溯需要另外处理。

代码

class Solution {
    vector<string> ret;
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        string path;
        dfs(root,path);
        return ret;
    }

    void dfs(TreeNode* root,string path){
        path += to_string(root->val);
        if(!root->left&&!root->right){
            ret.push_back(path);
            return;
        }
        path+="->";

        if(root->left) dfs(root->left,path);
        if(root->right) dfs(root->right,path);
    }
};
  1. vector<string> ret;: 用于存储所有找到的路径。
  2. vector<string> binaryTreePaths(TreeNode* root): 主函数,初始化路径字符串为空,然后调用 DFS 函数。
  3. void dfs(TreeNode* root, string path): 深度优先搜索函数,递归生成从根节点到叶子节点的路径。
    • path += to_string(root->val);: 将当前节点的值加入到路径中。
    • if (!root->left && !root->right) {: 如果当前节点是叶子节点,将当前路径加入结果集,并返回。
    • path += "->";: 如果当前节点不是叶子节点,将箭头符号加入路径,表示连接到下一个节点。
    • if (root->left) dfs(root->left, path);: 递归调用 DFS 函数,搜索左子树。

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

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

相关文章

【洛谷 P8780】[蓝桥杯 2022 省 B] 刷题统计 题解(贪心算法+模拟+四则运算)

[蓝桥杯 2022 省 B] 刷题统计 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a a a 道题目&#xff0c;周六和周日每天做 b b b 道题目。请你帮小明计算&#xff0c;按照计划他将在第几天实现做题数大于等于 n n n 题? 输入格式 输入一…

机器人内部传感器阅读笔记及心得-位置传感器-光电编码器

目前&#xff0c;机器人系统中应用的位置传感器一般为光电编码器。光电编码器是一种应用广泛的位置传感器&#xff0c;其分辨率完全能满足机器人的技术要求&#xff0c;这种非接触型位置传感器可分为绝对型光电编码器和相对型光电编码器。前者只要将电源加到用这种传感器的机电…

智慧驿站_智慧文旅驿站_轻松的驿站智慧公厕_5G智慧公厕驿站_5G模块化智慧公厕

多功能城市智慧驿站是在智慧城市建设背景下&#xff0c;所涌现的一种创新型社会配套设施。其中&#xff0c;智慧公厕作为城市智慧驿站的重要功能基础&#xff0c;具备社会配套不可缺少的特点&#xff0c;所以在应用场景上&#xff0c;拥有广泛的需求和要求。那么&#xff0c;城…

基于深度学习的红肉新鲜过期判决系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 系统构成与流程 4.2 模型训练与优化 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ...............................................…

Open CASCADE学习|为什么由Edge生成Wire不成功?

Wire 是一种复合形状&#xff0c;不是由几何形状构建的&#xff0c;而是由边缘的装配构建的。BRepBuilderAPI_MakeWire类可以从一个或多个Edge构建Wire&#xff0c;或将新Edge连接到现有Wire。 BRepBuilderAPI_MakeWire 类将Edge连接到Wire。添加新Edge时&#xff0c;如果其顶点…

力扣基础刷题---二分查找

704. 二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 中心思想&#xff1a;找到中间值&#xff0c;跟中间值比…

区块链游戏解说:什么是 Nine Chronicles

作者&#xff1a;lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a; Nine Chronicles Dashboard 什么是 Nine Chronicles Nine Chronicles 是一款去中心化的在线角色扮演游戏&#xff0c;标志着在线游戏和区块链技术的发展。 Nine Chroni…

阿里云OTA升级指南

阿里云OTA升级指南 OTA简介 OTA是Over-The-Air的缩写&#xff0c;中文意为“通过空中传输”。在计算机和通信技术领域中&#xff0c;OTA指的是通过无线网络等方式将软件、固件、配置文件等更新、下载、安装到设备上的一种技术手段。它可以实现远程升级和管理设备的软件和配置…

【Python】 剪辑法欠采样 CNN压缩近邻法欠采样

借鉴&#xff1a;关于K近邻&#xff08;KNN&#xff09;&#xff0c;看这一篇就够了&#xff01;算法原理&#xff0c;kd树&#xff0c;球树&#xff0c;KNN解决样本不平衡&#xff0c;剪辑法&#xff0c;压缩近邻法 - 知乎 但是不要看他里面的代码&#xff0c;因为作者把代码…

Paddlepaddle使用自己的VOC数据集训练目标检测(0废话简易教程)

一 安装paddlepaddle和paddledection&#xff08;略&#xff09; 笔者使用的是自己的数据集 二 在dataset目录下新建自己的数据集文件&#xff0c;如下&#xff1a; 其中 xml文件内容如下&#xff1a; 另外新建一个createList.py文件&#xff1a; # -- coding: UTF-8 -- imp…

云打印api接口收费吗?

随着近来云打印服务的发展&#xff0c;越来越多的用户都开始选择云打印服务。很多工具类、学习累的App和软件看到了这其中的甜头&#xff0c;也都想要对接云打印业务来完成变现。对接云打印服务则需要找到合适的平台进行api对接。那么云打印api接口收费吗&#xff1f;收费标准是…

TF卡辨别指南|拓优星辰

在存储领域&#xff0c;TF卡&#xff08;MicroSD卡&#xff09;是一种常见的存储设备&#xff0c;但市场上也存在着各种品牌和型号。为了帮助用户准确辨别TF卡&#xff0c;我们提供了以下辨别指南&#xff0c;以确保用户能够选择符合其需求的高性能、高可靠性的TF卡。 二、外观…

数据结构笔记1线性表及其实现

终于开始学习数据结构了 c语言结束之后 我们通过题目来巩固了 接下来我们来学习数据结构 这里我们将去认识到数据结构的一些基础知识&#xff0c;我在第一次学习的时候会很迷糊现在重新学习发现之前的时候还是因为c语言学的不牢固导致学习数据结构困难 这里 我会尽量的多写代码…

fast-planner代码解读【kino_replan_fsm.cpp】

概述 kino_replan_fsm.cpp订阅实时定位和目标点信息&#xff0c;每隔0.01s执行一次状态机&#xff0c;进行状态切换&#xff1b;每隔0.05s执行一次碰撞检测&#xff0c;按需进行重新规划。核心为执行变量exec_state_ 主要函数及作用 KinoReplanFSM::init 输入&#xff1a;句…

SD-WAN解决方案:企业异地组网挑战之视频会议

随着企业的发展&#xff0c;不少企业开始面临规模扩大、分公司组建、异地办公的需求。其中&#xff0c;远程视频会议作为企业异地管理和运营的重要组成部分&#xff0c;对网络稳定性和视频传输质量有较高的要求。在本文&#xff0c;我们将探讨企业视频会议遇到的网络问题以及这…

SpringBoot+Vue+MySQL:图书管理系统的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

面试经典150题——生命游戏

​"Push yourself, because no one else is going to do it for you." - Unknown 1. 题目描述 2. 题目分析与解析 2.1 思路一——暴力求解 之所以先暴力求解&#xff0c;是因为我开始也没什么更好的思路&#xff0c;所以就先写一种解决方案&#xff0c;没准写着写…

2月21日

Bean生命周期 过程概述 创建对象 实例化(构造方法) 依赖注入 初始化 执行Aware接口回调 执行BeanPostProcessor.psotProcessBeforeInitialization 执行InitializingBean回调(先执行PostConstruct) 执行BeanPsotProcessor.postProcessAfterInitialization 使用对象 销毁对象…

Javaweb之SpringBootWeb案例之切入点表达式的详细解析

3.3 切入点表达式 从AOP的入门程序到现在&#xff0c;我们一直都在使用切入点表达式来描述切入点。下面我们就来详细的介绍一下切入点表达式的具体写法。 切入点表达式&#xff1a; 描述切入点方法的一种表达式 作用&#xff1a;主要用来决定项目中的哪些方法需要加入通知 …

ffmpeg TS复用代码详解——mpegtsenc.c

一、mpegtsenc.c 整体架构 二、主要函数 mpegts_write_pes(AVFormatContext *s, AVStream *st, const uint8_t *payload, int payload_size, int64_t pts, int64_t dts)这个函数就是TS打包的主函数了&#xff0c;这个函数主要功能就是把一帧数据拆分成188字节的TS包&#xff0…