数据结构与算法----复习Part 14 (树与二叉树)

本系列是算法通关手册LeeCode的学习笔记

算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn)

目录

一,树(Tree)

树的相关术语

节点间关系

树的其他术语

二,二叉树(Binary Tree)

满二叉树(Full Binary Tree)

完全二叉树(Complete Binary Tree)

二叉搜索树(Binary Search Tree)

平衡二叉搜索树(Balanced Binary Tree)

三,二叉树的存储结构

顺序存储结构

链式存储结构

四,二叉树的遍历

二叉树的前序遍历

二叉树的中序遍历

二叉树的后序遍历

二叉树的层序遍历

五,二叉树的还原

从前序和中序序列构造二叉树:

从中序和后序序列构造二叉树

从前序和后序序列构造二叉树


 一,树(Tree)

        由 n >= 0 个节点与节点之间的关系组成的有限集合。 n = 0 时称空树,n > 0 时称非空树。

        树 具有以下特点:

                有且仅有一个节点没有前驱节点,该节点称为树的【根节点(Root)】;

                除了根节点之外,每个节点有且仅有一个直接前驱节点;

                包括根节点在内,每个节点可以有多个后继节点(一对多的关系);

                当 n > 1 时,除了根节点之外的其他节点与其后继节点组成的也是一棵树,称为根的

        【子树(Sub Tree)】;

树的相关术语

        

树的节点:由一个数据元素和若干个指向其子树的分支组成(节点 加 指向子树的箭头);

节点的度:一个节点所含有的子树个数;

叶子节点:度为 0 的节点,如图中的 C、F、H、I、G、K;

分支节点:度不为 0 的节点,如图中的 A、B、D、E、G;

数的度:树中节点的最大度数,如图中树的度为 3;

节点间关系

子节点:一个节点含有的【子树的根节点】称为该节点的子节点;

父节点:如果一个节点含有子节点,则称该节点为其子节点的父节点;

兄弟节点:具有相同父节点的节点互称为兄弟节点;

树的其他术语

节点的层次:从根节点开始定义,根为第 1 层,根的子节点为第 2 层,以此类推;

树的深度(高度):所有节点中最大的层数;

堂兄弟节点:父节点在同一层的节点互为堂兄弟;

路径:树中两个节点之间所经过的节点序列。如图中 E 到 G 的路径为 E-B-A-D-G;

路径长度:两个节点之间路径上经过的边数。如图中 E 到 G 的路径长度为 4;

节点的祖先:从该节点到根节点所经过的所有节点,被称为该节点的祖先。如图中 H 的祖先为 E、B、A;

节点的子孙:节点的子树中所有节点被称为该节点的子孙。例如图中 D 的子孙为 F、G、K

有序树:节点的各个子树从左至右有序,不能呼唤位置;

无序树:节点的各个子树可互换位置。

二,二叉树(Binary Tree)

        树中各个节点的度不大于 2 个的有序树,称为二叉树。通常树中的分支节点被称为【左子树】或【右子树】。二叉树的分支具有左右次序,不能随意互换位置。

        二叉树可以用递归的方式来定义,即二叉树满足以下两个要求之一:

                空树:二叉树是一个空树;

                非空树:二叉树是有一个根节点和两棵互不相交的子树,分别称为根节点的左子树、右

        子树组成的非空树,并且其本身都是二叉树。

        二叉树是种特殊的树,它最多有两个子树,分别为左子树和右子树,并且两个子树是有序的,不可以互换。也就是说,在二叉树种不存在度大于 2 的节点。

        二叉树在逻辑上可以分为 5 种基本形态

满二叉树(Full Binary Tree)

        如果所有分支节点都存在左子树和右子树,并且所有叶子节点都在同一层上,则称该二叉树为满二叉树。

        满二叉树满足:

                叶子节点只出现在最下面一层;

                非叶子节点的度一定为 2 ;

                在同等深度的二叉树中,满二叉树的节点个数最多,叶子节点个数最多。

        如果我们对满二叉树的节点进行编号。根节点编号为 1,然后按照层次依次向下,每一层从左到右的顺序进行编号,则深度为 k 的满二叉树最后一个节点的编号为 2^k - 1。

完全二叉树(Complete Binary Tree)

        如果叶子节点只能出现在最下面两层,并且最下层的叶子节点都依次排列在该层最左边的位置上,称为完全二叉树。

        完全二叉树满足:

                叶子节点只能出现在最下面两层;

                最下层的叶子节点一定集中在该层最左边的位置上;

                倒数第二层如果有叶子节点,则一定集中在右边位置上;

                如果节点的度为一,则该节点只有做孩子节点;

                

二叉搜索树(Binary Search Tree)

        也叫二叉查找树,是指一棵空树或具有以下性质的二叉树:

                如果任意节点的左子树不为空,则左子树上所有节点的值均小于它根节点的值;

                如果任意节点的右子树不为空,则右子树上所有节点的值均大于它根节点的值;

                任意节点的左子树、右子树均为二叉搜索树

平衡二叉搜索树(Balanced Binary Tree)

        一种结构平衡的二叉搜索树。即叶节点的高度差绝对值不超过 1,并且左右两个子树都是一棵平衡二叉搜索树。

三,二叉树的存储结构

        二叉树的存储结构分为两种:【顺序存储结构】和【链式存储结构】。

顺序存储结构

        其实,堆排序、优先队列中的二叉堆结构,采用的就是二叉树的顺序存储结构。

        二叉树的顺序存储结构使用一维数组在存储二叉树中的节点,节点存储位置则采用完全二叉树的节点层次编号,按照层次从上到下,每一层从左到右的顺序依次存放二叉树的数据元素。在进行顺序存储时,如果对应的二叉树节点不存在,则设置为空节点。

        可以看出节点之间的逻辑关系:

                如果某二叉树节点(非叶子节点)的下标为 i,那么其左孩子节点的下标为 i * i + 1,右

        孩子节点的下标为 2 * i + 2;

                如果某二叉树节点(非根节点)的下标为 i,那么其根节点的下标为 (i - 1) // 2

        对于完全二叉树(尤其是满二叉树)来说,采用顺序存储结构比较合适,它能充分利用存储空间,而对于一般二叉树,如果需要设置很多的【空节点】,则采用顺序存储结构就会浪费很多存储空间,并且由于顺序存储结构固有的一些缺陷,会使得二叉树的插入,删除等操作不方便,效率也比较低,对于二叉树来说,当数的形态和大小经常发生动态变化时,更适合采用链式存储结构。

链式存储结构

        二叉树采用链式存储结构时,每个节点包含一个用于数据域 val ,存储节点信息,还包含两个指针域 left 和 right ,分别指向左右两个孩子节点,当左孩子或右孩子不存在,相应指针域为空。

对应代码:

class TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = right

        二叉树的链表存储结构具有灵活、方便的特点。节点的最大数目只受系统最大可存储空间的限制。一般情况下,二叉树的链表存储结构比顺序存储结构更省空间,而对于二叉树实施相关操作也很方便,因此,一般使用链式存储结构来存储二叉树。

四,二叉树的遍历

        从根节点出发,按照某种次序依次访问二叉树中的所有节点,使得每个节点被访问依次且仅被访问一次。

        使用深度优先的方式遍历二叉树,分为二叉树的前、中、后序遍历。

        使用广度优先遍历二叉树,则是二叉树的层序遍历。

二叉树的前序遍历

        如果二叉树为空,则返回;

        如果二叉树不为空,则:

                访问根节点;

                以前序遍历的方式遍历根节点的左子树;

                以前序遍历的方式遍历根节点的右子树;

        可见前序遍历过程是一个递归过程,在遍历任何一棵子树时,仍然是按照先访问根节点,然后遍历子树根节点的左子树,最后遍历根节点的右子树的顺序进行遍历。

注意这里的访问,指的是得到该节点的 val 值,而不是进入该节点。

递归实现

class Solution:def preorderTraversal(self, root: TreeNode):res = []def preorder(root):if not root:returnres.append(root.val)preorder(root.left)preorder(root.right)preorder(root)return res

前序遍历的显示栈实现:

        根据栈先入后出的特点,先放入右子树,再放入左子树。

        判断二叉树是否为空,为空则直接返回;

        初始化维护一个栈,将根节点入栈;

        当栈不为空时:

                弹出栈顶元素 node,并访问该元素;

                如果 node 的右子树不为空,则将 node 的右子树入栈;

                如果 node 的左子树不为空,则将 node 的左子树入栈;

    def preorderTraversalStack(self, root):if not root:return []res = []stack = [root]while stack:node = stack.pop()res.append(node.val)if node.right:stack.append(node.right)if node.left:stack.append(node.left)return res

二叉树的中序遍历

        如果二叉树为空,则返回;

        如果二叉树不为空,则:

                以中序遍历的方式遍历根节点的左子树;

                访问根节点;

                以中序遍历的方式遍历根节点的右子树;

递归实现:

    def inorderTraversal(self, root: TreeNode):res = []def inorder(root):if not root:returninorder(root.left)res.append(root.val)inorder(root.right)inorder(root)return res

中序遍历的显式栈实现:

        访问根节点要在左子树遍历完之后,因此我们应该从根节点开始,循环遍历左子树,不断将当前子树的根节点放入栈中,直到当前节点无左子树时,从栈中弹出该节点并处理;

        判断二叉树是否为空,为空则直接返回;

        初始化维护一个空栈;

        当根节点或者栈不为空时,

                如果当前节点不为空,则遍历左子树,并不断把当前子树的根节点入栈;

                如果当前节点为空,则说明当前节点无左子树,则弹出栈顶元素 node,并访问,然后尝

        试访问该节点的右子树;

    def inorderTraversalStack(self, root):if not root:return []res = []stack = []while root or stack:while root:stack.append(root)root = root.leftnode = stack.pop()res.append(node.val)root = node.rightreturn res

二叉树的后序遍历

        如果二叉树为空,则返回;

        如果二叉树不为空,则

                以后序遍历的方式遍历根节点的左子树;

                以后序遍历的方式遍历根节点的右子树;

                访问根节点

递归实现:

    def postorderTraversal(self, root: TreeNode):res = []def postorder(root):if not root:return postorder(root.left)postorder(root.right)res.append(root.val)postorder(root)return res

后序遍历的显式栈实现

        后序遍历中,根节点的访问在左右子树访问之后。

        判断二叉树是否为空,为空则直接返回;

        初始化维护一个空栈,使用 prev 保存前一个访问的节点,用于确定当前节点的右子树是否已经访问完毕;

        当根节点或者栈不为空时,从当前节点开始:

                如果当前节点右左子树,则不断遍历左子树,并将当前根节点压入栈中;

                如果当前节点无左子树,则弹出栈顶元素 node;

                如果栈顶元素 node 无右子树或者右子树已经访问完毕,则访问该元素,然后记录前一

        节点,并将当前节点标记为空节点,意为需要栈弹出一个栈顶元素;

                如果栈顶元素 node 有右子树,则将栈顶元素重新压入栈中,继续访问栈顶元素的右子

        树。

    def postorderTraversalStack(self, root):res = []stack = []prev = Nonewhile root or stack:while root:stack.append(root)root = root.leftnode = stack.pop()if not node.right or node.right == prev:res.append(node.val)prev = noderoot = None     # 需要弹出新的栈顶元素else:stack.append(node)root = node.rightreturn res

二叉树的层序遍历

        如果二叉树为空,则返回;

        如果二叉树不为空,则:

                先依次访问二叉树第一层的节点;

                然后依次访问二叉树第二层的节点;

                ...

        层序遍历过程是一个广度优先搜索的过程

二叉树的层序遍历通过队列实现:

        判断二叉树是否为空,为空则直接返回;

        令根节点入队;

        当队列不为空时,求出当前队列长度 s;

        依次从队列中取出这 s 个元素,并对这 s 个元素依次进行访问,然后将其左右孩子节点入队,然后继续遍历下一层节点;

        当队列为空时,结束遍历;

实现代码:

    def levelOrder(self, root: TreeNode):if not root:return []queue = [root]order = []while queue:level = []size = len(queue)for _ in range(size):cur = queue.pop(0)level.append(cur.val)if cur.left:queue.append(cur.left)if cur.right:queue.append(cur.right)if level:order.append(level)return order

104. 二叉树的最大深度

class Solution:def maxDepth(self, root: Optional[TreeNode]) -> int:if not root :return 0return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

103. 二叉树的锯齿形层序遍历

import collections
class Solution:def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:if not root:return []queue = [root]order = []odd = Truewhile queue:level = collections.deque()size = len(queue)for _ in range(size):curr = queue.pop(0)if odd:level.append(curr.val)else:level.appendleft(curr.val)if curr.left:queue.append(curr.left)if curr.right:queue.append(curr.right)if level:order.append(list(level))odd = not oddreturn order

111. 二叉树的最小深度

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def minDepth(self, root: Optional[TreeNode]) -> int:if not root:return 0queue = [root]dep = 1while queue:n = len(queue)for i in range(n):node = queue.pop(0)if node.left == None and node.right == None:return depif node.left:queue.append(node.left)if node.right:queue.append(node.right)dep += 1return dep

        与最大不同,找树的最小深度算是广度遍历的经典应用场景,逐层的排查节点是否是叶子节点,能够找到树的最小深度。

五,二叉树的还原

        指的是通过二叉树的遍历序列,还原出对应的二叉树。

        这个部分比较抽象,所以建议找视频资源进行学习:

        比如:【已知二叉树中序、后序序列,如何还原二叉树?一道题搞定】 https://www.bilibili.com/video/BV1624y1t7Cg/share_source=copy_web&vd_source=87ace2077a752fc4561aff19bae87dac

         简单来说就是根据遍历过程中的规则,不断查找两个遍历结果,实现二叉树的还原,我们的重心在代码实现。而代码实现的重点在于充分明白所知序列能够发挥的作用。

前序序列作用,前序的遍历顺序是【根左右】,因此我们可以从中知道根节点的位置;

中序序列作用,中序遍历的顺序是【左根右】,因此我们知道根节点后,可以知道左子树与右子树的中序序列

后序序列作用,后序遍历的顺序是【左右根】,我们可以知道根节点的位置。

        开始代码实现之前,我们要明确的是,只有前序和后序无法唯一确定二叉树。

从前序和中序序列构造二叉树:

        从前序遍历序列中得到当前根节点位置在 preorder[ 0 ];

        通过在中序遍历中查找上一步根节点对应位置 inorder[ k ],从而将二叉树左右子树分隔开,并得到左右子树节点个数;

        从上一步得到的左右子树个节点个数,将前序序列中的左右子树分开;

        构造当前节点,并递归建立左右树,在左右树的对应位置继续递归遍历并执行上述三步,直到节点为空

    def buildTreeFromPreIn(self, preorder, inorder):def createTree(preorder, inorder, n):if n == 0:return Nonek = 0while preorder[0] != inorder[k]:k += 1  #   找到中序遍历的分隔位置node = TreeNode(inorder[k])node.left = createTree(preorder[1: k + 1], inorder[0: k], k)node.right = createTree(preorder[k + 1: ], inorder[k + 1: ], n - k - 1)return nodereturn createTree(preorder, inorder, len(inorder))

从中序和后序序列构造二叉树

        从后序序列中得到当前根节点的位置在 postorder[ n - 1 ];

        通过在中序遍历中查找根节点对应的位置 inorder[k],从而将二叉树的所有子树分隔开,并得到左右子树的节点个数;

        从上一步得到的左右子树节点个数,将后序序列中的左右子树分开;

        构造当前节点,并递归建立左右子树,并在左右子树对应位置继续递归执行上述三步,直到节点为空

    def buildTreeFromInPost(self, inorder, postorder):def createTree(inorder, postorder, n):if n == 0:return Nonek = 0while postorder[n - 1] != inorder[k]:k += 1node = TreeNode(inorder[k])node.right = createTree(inorder[k + 1: n], postorder[k: n - 1], n - k - 1)node.left = createTree(inorder[0: k], postorder[0: k], k)return nodereturn createTree(inorder, postorder, len(postorder))

从前序和后序序列构造二叉树

        我们可以默认指定前序序列的第 2 个值为左子树的根节点,由此递归划分左右子树。

        从前序遍历序列中可知当前根节点的位置在 preorder[ 0 ];

        从前序序列的第二个值为左子树的根节点,通过在后序序列中查找上一步根节点对应的位置,postorder[ k ]。从而将二叉树的左右子树分隔开,从得到左右子树节点的个数.

        从上一步得到的左右子树个数,将后序序列结果中的左右子树分开;

        构造当前节点,并递归建立左右子树,在左右子树对应位置继续递归遍历并执行上述三步,直到节点为空。

 def constructFromPrePost(self, preorder: List[int], postorder: List[int]) -> TreeNode:def createTree(preorder, postorder, n):if n == 0:return Nonenode = TreeNode(preorder[0])if n == 1:return nodek = 0while postorder[k] != preorder[1]:k += 1node.left = createTree(preorder[1: k + 2], postorder[: k + 1], k + 1)node.right = createTree(preorder[k + 2: ], postorder[k + 1: -1], n - k - 2)return nodereturn createTree(preorder, postorder, len(preorder))

算法通关手册(LeetCode) | 算法通关手册(LeetCode)

原文内容在这里,如有侵权,请联系我删除。

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

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

相关文章

【深度学习笔记】8_1 命令式和符号式混合编程

注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图 8.1 命令式和符号式混合编程 本书到目前为止一直都在使用命令式编程,它使用编程语句改变程序状态。考虑下面这段简单的命令…

比较JavaScript中的for...in和for...of循环

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

linux解析域名指令 nslookup 或者 host

host www.baidu.com 第二种方法 nslookup www.baidu.com 注意:ns是name server之意

【包邮送书】Elasticsearch 通过索引阻塞实现数据保护深入解析

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关…

运维工程师面试题

1. CPU性能指标中,以下指标代表什么意思? 外频:CPU的基准频率,CPU与主板之间同步运行的速度,它决定整个主板的运行速率。 前端总线频率:直接影响CPU和内存数据交换的速度。 2. 主板的两个芯片分别是什么…

uView Upload 上传

该组件用于上传图片场景 #平台差异说明 App&#xff08;vue&#xff09;App&#xff08;nvue&#xff09;H5小程序√√√√ #基础用法 可以通过设置fileList参数(数组&#xff0c;元素为对象)&#xff0c;显示预置的图片。其中元素的url属性为图片路径 <template>&l…

面试经典-9-跳跃游戏

题目 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff…

回收小程序系统后台管理功能

会员管理&#xff1a;管理员可以查看和管理会员的基本信息&#xff0c;如姓名、联系方式、寄送地址和订单记录等。 产品管理&#xff1a;对回收物品进行管理&#xff0c;包括分类、规格设定、数据统计等。 订单管理&#xff1a;对所有订单进行追踪和管理&#xff0c;确保订单处…

Leetcode 543. 二叉树的直径

题目描述&#xff1a; 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;ro…

汽车屏类产品(五):仪表Cluster常用芯片i.MX117x

前言: 仪表一般就是指方向盘前面那个表盘。做仪表的芯片最主要需要支持显示Display,而仪表的主要排版布局多种多样,但是主旨显示内容不尽相同。 仪表需求: 1、rpm转速表盘 仪表Cluster一般会有转速表盘rpm,单位一般是x1000,大部分汽车仪表范围就是0~8,也就是最高8000…

MySQL安装使用(mac、windows)

目录 macOS环境 一、下载MySQL 二、环境变量 三、启动 MySql 四、初始化密码设置 windows环境 一、下载 二、 环境配置 三、安装mysql 1.初始化mysql 2.安装Mysql服务 3.更改密码 四、检验 1.查看默认安装的数据库 2.其他操作 macOS环境 一、下载MySQL 打开 MyS…

用 Qt 不怕被告吗?

用 Qt 不怕被告吗? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Qt 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 收律师函不…

Gitea相关漏洞

Go代码审计&#xff1a;Gitea远程命令执行漏洞链_新闻中心-网盾网络安全培训学校 Vulhub靶场gitea-1.4远程代码执行漏洞复现_gitea 漏洞-CSDN博客

java Lambda表达式如何支持实例方法引用

java Lambda表达式如何支持实例方法引用 在Java中&#xff0c;Lambda表达式确实支持实例方法引用。实例方法引用允许你引用一个对象实例的某个方法&#xff0c;并将其作为Lambda表达式的实现。这提供了一种简洁的方式来表示Lambda表达式&#xff0c;特别是当Lambda表达式仅仅是…

云浮肇庆三维扫描钣金铸件抄数逆向设计外观画3D图上门抄数服务

钣金铸件抄数逆向设计画图是一项精密而富有挑战性的工作&#xff0c;它要求工程师具备深厚的专业知识和丰富的实践经验。3D抄数&#xff0c;即是通过精密测量设备获取钣金铸件的三维数据&#xff0c;为后续的逆向设计提供基础。逆向设计则是指根据已有的实物或模型&#xff0c;…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:StepperItem)

用作Stepper组件的页面子组件。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 支持单个子组件。 接口 StepperItem() 属性 参数名参数类型参数描述prevLabelstring设置左侧文本按钮内…

2024年软考计划开始了,你准备好了吗?

目录标题 2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划计算机软考中级科目哪个含金量最高&#xff1f;报考流程和说明 2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划 一、2024年度计算机软件资格考试(初级…

每日一面——成员初始化列表、移动构造和拷贝构造

写前声明&#xff1a;参考链接 C面经、面试宝典 等 ✊✊✊每日一面——成员初始化列表、移动构造和拷贝构造 一、类成员初始化方式&#xff1f;构造函数的执行顺序&#xff1f;为什么用成员初始化列表会快一些&#xff1f;二、final和override关键字三、拷贝初始化和直接初始化…

自动点名器

班级里有N个学生&#xff0c;实现随机点名器 package MyApi.a00test;import java.util.ArrayList; import java.util.Collections; import java.util.Random;public class Test1 {public static void main(String[] args) {ArrayList<String> listnew ArrayList<>…

<Linux> 线程控制

目录 一、线程资源的分配 &#xff08;一&#xff09;线程私有资源 &#xff08;二&#xff09;线程共享资源 二、原生线程库 三、线程控制接口 &#xff08;一&#xff09;线程创建 - pthread_create() 1. 一个线程 2. 一批线程 &#xff08;二&#xff09;线程等待 …