代码随想录算法训练营第十八天:二叉树的层序遍历(中间放假)

代码随想录算法训练营第十八天:二叉树的层序遍历(中间放假)

我要打十个

102.二叉树的层序遍历

力扣题目链接(opens new window)

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

102.二叉树的层序遍历

#思路

我们之前讲过了三篇关于二叉树的深度优先遍历的文章:

  • 二叉树:前中后序递归法(opens new window)
  • 二叉树:前中后序迭代法(opens new window)
  • 二叉树:前中后序迭代方式统一写法(opens new window)

接下来我们再来介绍二叉树的另一种遍历方式:层序遍历。

层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。

需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。

而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。

使用队列实现二叉树广度优先遍历,动画如下:

102二叉树的层序遍历

这样就实现了层序从左到右遍历二叉树。

代码如下:这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了

c++代码如下:

class Solution {
public:vector<vector<int>> levelOrder(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<vector<int>> result;while (!que.empty()) {int size = que.size();vector<int> vec;// 这里一定要使用固定大小size,不要使用que.size(),因为que.size是不断变化的for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(vec);}return result;}
};
# 递归法
class Solution {
public:void order(TreeNode* cur, vector<vector<int>>& result, int depth){if (cur == nullptr) return;if (result.size() == depth) result.push_back(vector<int>());result[depth].push_back(cur->val);order(cur->left, result, depth + 1);order(cur->right, result, depth + 1);}vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> result;int depth = 0;order(root, result, depth);return result;}
};

107.二叉树的层次遍历 II

力扣题目链接(opens new window)

给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

107.二叉树的层次遍历II

思路

相对于102.二叉树的层序遍历,就是最后把result数组反转一下就可以了。

C++代码:

class Solution {
public:vector<vector<int>> levelOrderBottom(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<vector<int>> result;while (!que.empty()) {int size = que.size();vector<int> vec;for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();vec.push_back(node->val);if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(vec);}reverse(result.begin(), result.end()); // 在这里反转一下数组即可return result;}
};

199.二叉树的右视图

力扣题目链接(opens new window)

给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

199.二叉树的右视图

#思路

层序遍历的时候,判断是否遍历到单层的最后面的元素,如果是,就放进result数组中,随后返回result就可以了。

C++代码:

/*** 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 {
vector <int> ans;
void dfs(TreeNode *node ,int depth){if (node == nullptr)return ;if (depth == ans.size())ans.push_back(node->val);dfs(node->right,depth + 1);dfs(node->left,depth+1);
}
public:vector<int> rightSideView(TreeNode* root) {dfs(root,0);return ans;}
};

637.二叉树的层平均值

力扣题目链接(opens new window)

给定一个非空二叉树, 返回一个由每层节点平均值组成的数组。

637.二叉树的层平均值

#思路

本题就是层序遍历的时候把一层求个总和在取一个均值。

C++代码:

/*** 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<double> averageOfLevels(TreeNode* root) {queue<TreeNode*> que;if(root != NULL) que.push(root) ;vector<double> result;while(!que.empty()){int size = que.size();double sum = 0;for(int i = 0;i< size;i++){TreeNode* node = que.front();que.pop();sum += node->val;if(node->left)que.push(node->left);if(node->right)que.push(node->right);}result.push_back(sum/size);}return result;}
};

429.N叉树的层序遍历

力扣题目链接(opens new window)

给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。

例如,给定一个 3叉树 :

429. N叉树的层序遍历

返回其层序遍历:

[ [1], [3,2,4], [5,6] ]

#思路

这道题依旧是模板题,只不过一个节点有多个孩子了

/*
// Definition for a Node.
class Node {
public:int val;vector<Node*> children;Node() {}Node(int _val) {val = _val;}Node(int _val, vector<Node*> _children) {val = _val;children = _children;}
};
*/class Solution {
public:vector<vector<int>> levelOrder(Node* root) {if(!root){return {};}vector<vector<int>> ans;queue<Node*> q;q.push(root);while(!q.empty()){int cnt = q.size();vector<int> level;for(int i = 0;i<cnt;++i){Node* cur = q.front();q.pop();level.push_back(cur->val);for(Node* child:cur->children){q.push(child);}}ans.push_back(move(level));}return ans;}
};

515.在每个树行中找最大值

力扣题目链接(opens new window)

您需要在二叉树的每一行中找到最大的值。

515.在每个树行中找最大值

#思路

层序遍历,取每一层的最大值

C++代码:

class Solution {
public:vector<int> largestValues(TreeNode* root) {queue<TreeNode*> que;if (root != NULL) que.push(root);vector<int> result;while (!que.empty()) {int size = que.size();int maxValue = INT_MIN; // 取每一层的最大值for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();maxValue = node->val > maxValue ? node->val : maxValue;if (node->left) que.push(node->left);if (node->right) que.push(node->right);}result.push_back(maxValue); // 把最大值放进数组}return result;}
};
/*** 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> largestValues(TreeNode* root) {vector<int> ans;auto dfs = [&](auto && dfs,auto&& r,int d){if(!r) return;if(ans.size () == d)ans.emplace_back(r->val);else ans[d] = max(ans[d],r->val);dfs(dfs,r->left,d+1);dfs(dfs,r->right,d+1);};dfs(dfs,root,0);return ans;}
};

116.填充每个节点的下一个右侧节点指针

力扣题目链接(opens new window)

给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {int val;Node *left;Node *right;Node *next;
}

填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

116.填充每个节点的下一个右侧节点指针

#思路

本题依然是层序遍历,只不过在单层遍历的时候记录一下本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了

C++代码:

class Solution {
public:Node* connect(Node* root) {queue<Node*> que;if (root != NULL) que.push(root);while (!que.empty()) {int size = que.size();// vector<int> vec;Node* nodePre;Node* node;for (int i = 0; i < size; i++) {if (i == 0) {nodePre = que.front(); // 取出一层的头结点que.pop();node = nodePre;} else {node = que.front();que.pop();nodePre->next = node; // 本层前一个节点next指向本节点nodePre = nodePre->next;}if (node->left) que.push(node->left);if (node->right) que.push(node->right);}nodePre->next = NULL; // 本层最后一个节点指向NULL}return root;}
};

迭代解法二

题目要求是常量的辅助空间,所以第一种解法并不符合要求,下面来看下 O(1)O(1) O ( 1 ) 空间复杂度的实现细节。
注意,题目说的二叉树是一棵完美二叉树,即每一层的节点都是满的。
仔细看下完成后的串联树,其连接的方式有两种:
第一种 是这两个串联的节点都有一个共同的父节点,通过父节点就可以将这两个子节点串联起来

3.jpg
{:align=center}

第二种 是这两个串联的节点的父节点不同,对于这种情况,如果我们能将这一层的上一层串联好。那么可以通过父节点的next​找到邻居,完成串联。

4.jpg
{:align=center}

root.right.next => root.next.left

这里我们需要保证 root.next​ 不为空就可以了。
也就是说当我们要串联第 i​ 层节点时,需要先完成第 i-1​ 层的节点串联
第一层最多只有一个节点,不需要串联
第二层最多只有两个节点,借助根节点就可以完成串联了
第三层串联时,上一层已经串联完了,所以第三层可以完成串联
同理,可以完成第四层,第五层,第N层的串联

5.gif
{:align=center}

时间复杂度:O(n)O(n) O ( n )
空间复杂度:O(1)O(1) O ( 1 )

leftmost = root
while (leftmost.left != null) {head = leftmostwhile (head.next != null) {1) Establish Connection 12) Establish Connection 2 using next pointershead = head.next}leftmost = leftmost.left
}
class Solution {
public:Node* connect(Node* root) {if (root == nullptr) {return root;}// 从根节点开始Node* leftmost = root;while (leftmost->left != nullptr) {// 遍历这一层节点组织成的链表,为下一层的节点更新 next 指针Node* head = leftmost;while (head != nullptr) {// CONNECTION 1head->left->next = head->right;// CONNECTION 2if (head->next != nullptr) {head->right->next = head->next->left;}// 指针向后移动head = head->next;}// 去下一层的最左的节点leftmost = leftmost->left;}return root;}
};

117.填充每个节点的下一个右侧节点指针II

力扣题目链接(opens new window)

#思路

这道题目说是二叉树,但116题目说是完整二叉树,其实没有任何差别,一样的代码一样的逻辑一样的味道

C++代码:

class Solution {
public:Node* connect(Node* root) {queue<Node*> que;if (root != NULL) que.push(root);while (!que.empty()) {int size = que.size();vector<int> vec;Node* nodePre;Node* node;for (int i = 0; i < size; i++) {if (i == 0) {nodePre = que.front(); // 取出一层的头结点que.pop();node = nodePre;} else {node = que.front();que.pop();nodePre->next = node; // 本层前一个节点next指向本节点nodePre = nodePre->next;}if (node->left) que.push(node->left);if (node->right) que.push(node->right);}nodePre->next = NULL; // 本层最后一个节点指向NULL}return root;}
};
方法二:使用已建立的 next\text{next} next 指针

思路与算法

因为必须处理树上的所有节点,所以无法降低时间复杂度,但是可以尝试降低空间复杂度。

在方法一中,因为对树的结构一无所知,所以使用队列保证有序访问同一层的所有节点,并建立它们之间的连接。然而不难发现:一旦在某层的节点之间建立了 next\text{next} next 指针,那这层节点实际上形成了一个链表。因此,如果先去建立某一层的 next\text{next} next 指针,再去遍历这一层,就无需再使用队列了。

基于该想法,提出降低空间复杂度的思路:如果第 iii 层节点之间已经建立 next\text{next} next 指针,就可以通过 next\text{next} next 指针访问该层的所有节点,同时对于每个第 iii 层的节点,我们又可以通过它的 left\rm leftleft 和 right\rm rightright 指针知道其第 i+1i+1i + 1 层的孩子节点是什么,所以遍历过程中就能够按顺序为第 i+1i + 1i + 1 层节点建立 next\text{next} next 指针。

具体来说:

  • 从根节点开始。因为第 000 层只有一个节点,不需要处理。可以在上一层为下一层建立 next\text{next} next 指针。该方法最重要的一点是:位于第 xxx 层时为第 x+1x + 1x + 1 层建立 next\text{next} next 指针。一旦完成这些连接操作,移至第 x+1x + 1x + 1 层为第 x+2x + 2x + 2 层建立 next\text{next} next 指针。
  • 当遍历到某层节点时,该层节点的 next\text{next} next 指针已经建立。这样就不需要队列从而节省空间。每次只要知道下一层的最左边的节点,就可以从该节点开始,像遍历链表一样遍历该层的所有节点。
/*
// Definition for a Node.
class Node {
public:int val;Node* left;Node* right;Node* next;Node() : val(0), left(NULL), right(NULL), next(NULL) {}Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}Node(int _val, Node* _left, Node* _right, Node* _next): val(_val), left(_left), right(_right), next(_next) {}
};
*/class Solution {
public:void handle(Node* &last,Node* &p,Node* &nextStart){if(last){last->next = p;}if(!nextStart){nextStart = p;}last = p;}Node* connect(Node* root) {if(!root){return nullptr;}Node* start = root;while(start){Node* last = nullptr,*nextStart = nullptr;for(Node *p = start;p!=nullptr;p = p->next){if(p->left){handle(last,p->left,nextStart);}if(p->right){handle(last,p->right,nextStart);}}start = nextStart;}return root;}
};

104.二叉树的最大深度

力扣题目链接(opens new window)

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7],

104. 二叉树的最大深度

返回它的最大深度 3 。

#思路

使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。

在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度,如图所示:

层序遍历

所以这道题的迭代法就是一道模板题,可以使用二叉树层序遍历的模板来解决的。

C++代码如下:

class Solution {
public:int maxDepth(TreeNode* root) {if (root == NULL) return 0;int depth = 0;queue<TreeNode*> que;que.push(root);while(!que.empty()) {int size = que.size();depth++; // 记录深度for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);}}return depth;}
};

111.二叉树的最小深度

力扣题目链接(opens new window)

#思路

相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。

需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点

代码如下:(详细注释)

class Solution {
public:int minDepth(TreeNode* root) {if (root == NULL) return 0;int depth = 0;queue<TreeNode*> que;que.push(root);while(!que.empty()) {int size = que.size();depth++; // 记录最小深度for (int i = 0; i < size; i++) {TreeNode* node = que.front();que.pop();if (node->left) que.push(node->left);if (node->right) que.push(node->right);if (!node->left && !node->right) { // 当左右孩子都为空的时候,说明是最低点的一层了,退出return depth;}}}return depth;}
};

总结

二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时又发现队列的一个应用了)。

来吧,一口气打十个:

  • 102.二叉树的层序遍历(opens new window)
  • 107.二叉树的层次遍历II(opens new window)
  • 199.二叉树的右视图(opens new window)
  • 637.二叉树的层平均值(opens new window)
  • 429.N叉树的层序遍历(opens new window)
  • 515.在每个树行中找最大值(opens new window)
  • 116.填充每个节点的下一个右侧节点指针(opens new window)
  • 117.填充每个节点的下一个右侧节点指针II(opens new window)
  • 104.二叉树的最大深度(opens new window)
  • 111.二叉树的最小深度(opens new window)

致敬叶师傅!

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

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

相关文章

Java 框架安全:Struts2 漏洞序列测试.

什么是 Struts2 框架 Struts 2 是一个用于创建企业级 Java 应用程序的开源框架。它是一个 MVC&#xff08;模型-视图-控制器&#xff09;框架&#xff0c;用于开发基于 Java EE&#xff08;Java Platform, Enterprise Edition&#xff09;的 Web 应用程序。Struts 2 主要解决…

【Linux】HTTPS

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;Linux 目录 &#x1f449;&#x1f3fb;HTTPS协议概念&#x1f449;&#x1f3fb;加密为什么要进行加密 &#x1f449;&#x1f3fb;常见的加密方式对称加密…

【MATLAB源码-第204期】基于matlab的语音降噪算法对比仿真,谱减法、维纳滤波法、自适应滤波法;参数可调。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 语音降噪技术的目的是改善语音信号的质量&#xff0c;通过减少或消除背景噪声&#xff0c;使得语音更清晰&#xff0c;便于听者理解或进一步的语音处理任务&#xff0c;如语音识别和语音通讯。在许多实际应用中&#xff0c;如…

基于FPGA的DDS波形发生器VHDL代码Quartus仿真

名称&#xff1a;基于FPGA的DDS波形发生器VHDL代码Quartus仿真&#xff08;文末获取&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; DDS波形发生器VHDL 1、可以输出正弦波、方波、三角波 2、可以控制输出波形的频率 DDS波形发生器原理…

怎样扫描二维码后看图片?图片二维码的制作方式

二维码是一种可以用来存储大量内容&#xff0c;通过扫描二维码的方式来向其他人提供内容&#xff0c;比较常见的展示内容有视频、图片、文件、文本、音频等。那么图片生成二维码的方法是什么样的呢&#xff1f;通过扫码查看图片&#xff0c;可以不下载的图片的同时快速预览内容…

护眼台灯品牌排行前十名有哪些?最新护眼台灯品牌排行前十名分享

在近几年&#xff0c;一个引人关注的健康现象是青少年近视问题的日益加剧。统计数字显示&#xff0c;近视的发病率不断攀升&#xff0c;令人忧心地发现&#xff0c;许多才刚步入小学一年级的孩子们&#xff0c;便已佩戴起了厚重的眼镜。其中最主要的原因就在于学习过程对数码设…

当AI遇见现实:数智化时代的人类社会新图景

文章目录 一、数智化时代的机遇二、数智化时代的挑战三、如何适应数智化时代《图解数据智能》内容简介作者简介精彩书评目录精彩书摘强化学习什么是强化学习强化学习与监督学习的区别强化学习与无监督学习的区别 前言/序言 随着科技的日新月异&#xff0c;我们步入了一个前所未…

电镀回用水除镍树脂的一种设备方法

【除镍树脂CH-90】是一种专门设计用于去除溶液中镍离子的高效吸附材料。随着工业发展和环境保护要求的提高&#xff0c;除镍树脂CH-90在废水处理、金属回收和环境保护等领域的应用越来越广泛。 除镍树脂CH-90的特点在于其高效的吸附性能和选择性。该树脂能够快速、准确地去除溶…

Deeplab的复现(pytorch实现)

DeepLab复现的pytorch实现 本文复现的主要是deeplabv3。使用的数据集和之前发的文章FCN一样&#xff0c;没有了解的可以移步到之前发的文章中去查看一下。 1.该模型的主要结构 对于代码部分&#xff0c;主要只写了模型部分的&#xff0c;其他部分内容基本和FCN的一致&#xf…

Anaconda删除虚拟环境目录pkgs和envs|conda瘦身

这个文件夹里面是专门放不同环境中的包的&#xff0c;只是没有区分环境&#xff0c;都混在一起了&#xff0c; 一般在想要删除一个虚拟环境&#xff0c;除了在命令行中输入conda remove -n your_env_name(虚拟环境名称) --all 然后在envs中删除虚拟环境的文件夹&#xff0c; 还…

密码学《图解密码技术》 记录学习 第十三章

目录 第十三章 13.1 本章学习的内容 13.2 PGP 简介 13.2.1 什么是 PGP 13.2.2 关于 OpenPGP 13.2.3关于GNU Privacy Guard 13.2.4 PGP 的功能 公钥密码 数字签名 单向散列函数 证书 压缩 文本数据 大文件的拆分和拼合 13.3 生成密钥对 13.4 加密与解密 13.4.1 加密 生成…

《ESP8266通信指南》12-Lua 固件烧录

往期 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP8266通信指南》10-MQTT通信&#xff08;Arduino开发&#xff09;-CSDN博客 《ESP8266通信指南》9-TCP通信&#xff08;Arudino开发&#xff09;-CSDN博客 《ESP8266通信指南》8-连接WIFI&#xff08;Arduino开发…

牛客周赛 Round 41 C-F

C 小红的循环移位 思路&#xff1a; 一个数是不是四的倍数&#xff0c;只用看最后两位是否能够整除4即可。 #include <bits/stdc.h>using namespace std; const int N 1e6 5; typedef long long ll; typedef pair<ll, ll> pll; typedef array<ll, 3> p3;…

分布式与一致性协议之ZAB协议(五)

ZAB协议 ZAB集群如何从故障中恢复 如果我们想把ZAB集群恢复到正常状态&#xff0c;那么新领导者就必须确立自己的领导关系&#xff0c;成为唯一有效的领导者&#xff0c;然后作为主节点"领导"各备份节点一起处理读写请求 如何确立领导关系 前面提到&#xff0c;选…

VISO流程图之子流程的使用

子流程的作用 整个流程图的框图多而且大&#xff0c;进行分块&#xff1b;让流程图简洁对于重复使用的流程&#xff0c;可以归结为一个子流程图&#xff0c;方便使用&#xff0c;避免大量的重复性工作&#xff1b; 新建子流程 方法1&#xff1a; 随便布局 框选3 和4 &#…

【busybox记录】【shell指令】sort

目录 内容来源&#xff1a; 【GUN】【sort】指令介绍 【busybox】【sort】指令介绍 【linux】【sort】指令介绍 使用示例&#xff1a; 排序 - 默认排序 排序 - 检查所给文件是否已经排序 排序 - 输出已经排序过的文件&#xff0c;不会重新排序 排序 - 忽略每行前面的空…

【区块链】智能合约简介

智能合约起源 智能合约这个术语至少可以追溯到1995年&#xff0c;是由多产的跨领域法律学者尼克萨博&#xff08;NickSzabo&#xff09;提出来的。他在发表在自己的网站的几篇文章中提到了智能合约的理念。他的定义如下&#xff1a;“一个智能合约是一套以数字形式定义的承诺&a…

人工智能|推荐系统——工业界的推荐系统之交叉

Factorized Machine 线性模型预测是特征的加权和。&#xff08;只有加&#xff0c;没有乘。&#xff09; 二阶特征交叉 可以通过矩阵分解减少模型参数量 深度交叉网络&#xff08;DCN&#xff09; 之前提到过的召回、排序模型中的神经网络可以用任意网络结构&#xff1b;常见的…

数组折半法查找数据(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h> //定义数据&#xff1b; #define N 15int main() {//初始化变量值&#xff1b;int a[N], i, top, bott, loca, flag 1, sign, numb…

Ansible --- playbook 脚本+inventory 主机清单

一 inventory 主机清单 Inventory支持对主机进行分组&#xff0c;每个组内可以定义多个主机&#xff0c;每个主机都可以定义在任何一个或 多个主机组内。 如果是名称类似的主机&#xff0c;可以使用列表的方式标识各个主机。vim /etc/ansible/hosts[webservers]192.168.10.1…