队列(8.6)
目录
2.队列
2.1队列的概念及结构
2.2队列的实现
2.2.1初始化队列
2.2.2队尾入队列
2.2.3队头出队列
2.2.4获取队列头部元素
2.2.5 销毁队列
3.栈和队列面试题
225. 用队列实现栈 - 力扣(LeetCode)
232. 用栈实现队列 - 力扣(LeetCode)
编辑
622. 设计循环队列 - 力扣(LeetCode)
编辑
2.队列
2.1队列的概念及结构

将队列运用于抽号机能够计算出排队需要的等待的时间,需要等待前面的人数等信息,也能实现叫号(取队头)操作,能够实现绝对的公平,不存在插队现象。
2.2队列的实现

2.2.1初始化队列
// 初始化队列
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}
2.2.2队尾入队列
// 队尾入队列
void QueuePush(Que* pq, QDataType x)
{assert(pq);//开辟新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(-1);}//初始化新节点newnode->data = x;newnode->next = NULL;//判断队列是否为空if (pq->tail == NULL){pq->head = pq->tail = newnode;}//不为空尾插else{pq->tail->next = newnode;pq->tail = newnode;}
}
2.2.3队头出队列

// 队头出队列
void QueuePop(Que* pq)
{assert(pq);//列表不能为空assert(!QueueEmpty(pq));//如果列表只剩一个成员if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}//正常头删else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}
2.2.4获取队列头部元素
// 获取队列头部元素
QDataType QueueFront(Que* pq)
{assert(pq);//检查列表不为空assert(!QueueEmpty(pq));return pq->head->data;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq)
{assert(pq);//列表为空返回1,不为空返回0return pq->head == NULL;
}
2.2.5 销毁队列
// 销毁队列
void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}
2.2.6 探空
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq)
{assert(pq);//列表为空返回1,不为空返回0return pq->head == NULL;
}
3.栈和队列面试题
225. 用队列实现栈 - 力扣(LeetCode)

分析:创建两个队列入队列:入不为空的队列出队列:出不为空的前n-1个元素,插入到空队列,删除剩余元素




typedef int QDataType;typedef struct QueueNode
{QDataType data;struct QueueNode* next;}QNode;
typedef struct Que
{QNode* head;QNode* tail;int size;
}Que;// 初始化队列
void QueueInit(Que* pq);
// 队尾入队列
void QueuePush(Que* pq, QDataType x);
// 队头出队列
void QueuePop(Que* pq);
// 获取队列头部元素
QDataType QueueFront(Que* pq);
// 获取队列队尾元素
QDataType QueueBack(Que* pq);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq);
// 销毁队列
void QueueDestroy(Que* pq);
//队列节点数
int QueueSize(Que* pq);// 初始化队列
void QueueInit(Que* pq)
{assert(pq);pq->head = pq->tail = NULL;pq->size = 0;
}// 队尾入队列
void QueuePush(Que* pq, QDataType x)
{assert(pq);//开辟新节点QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("malloc");exit(-1);}//初始化新节点newnode->data = x;newnode->next = NULL;//判断队列是否为空if (pq->tail == NULL){pq->head = pq->tail = newnode;pq->size++;}//不为空尾插else{pq->tail->next = newnode;pq->tail = newnode;pq->size++;}
}// 队头出队列
void QueuePop(Que* pq)
{assert(pq);//列表不能为空assert(!QueueEmpty(pq));//如果列表只剩一个成员if (pq->head->next == NULL){free(pq->head);pq->head = pq->tail = NULL;}//正常头删else{QNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}// 获取队列头部元素
QDataType QueueFront(Que* pq)
{assert(pq);//检查列表不为空assert(!QueueEmpty(pq));return pq->head->data;
}// 获取队尾元素
QDataType QueueBack(Que* pq)
{assert(pq);//检查列表不为空assert(!QueueEmpty(pq));return pq->tail->data;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Que* pq)
{assert(pq);//列表为空返回1,不为空返回0return pq->head == NULL;
}
// 销毁队列
void QueueDestroy(Que* pq)
{assert(pq);QNode* cur = pq->head;while (cur){QNode* next = cur->next;free(cur);cur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}
//队列节点数
int QueueSize(Que* pq)
{assert(pq);return pq->size;
}//定义列表的结构体
typedef struct {Que q1;Que q2;
} MyStack;
//列表初始化
MyStack* myStackCreate() {//不能直接初始化,临时变量,出函数销毁,需要开辟空间MyStack* pst=(MyStack*)malloc(sizeof(MyStack));//参数为队列的指针QueueInit(&pst->q1);QueueInit(&pst->q2);return pst;
}void myStackPush(MyStack* obj, int x) {//谁不为空push到谁if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1,x);}else{QueuePush(&obj->q2,x);}
}
//出栈
int myStackPop(MyStack* obj) {//随便假设一个为空队列,一个为非空Que* empty=&obj->q1;Que* nonempty=&obj->q2;//如果假设错误,就交换if(!QueueEmpty(&obj->q1)){nonempty=&obj->q1;empty=&obj->q2;}//将非空栈出到剩尾元素为止while(QueueSize(nonempty)>1){//非空栈入到空栈QueuePush(empty,QueueFront(nonempty));//入一个出一个QueuePop(nonempty);}//保存尾元素int top=QueueFront(nonempty);//出掉尾元素QueuePop(nonempty);return top;}
//取栈顶
int myStackTop(MyStack* obj) {//谁不为空取谁的队尾if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}
//探空
bool myStackEmpty(MyStack* obj) {//两个列表都空才为空return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}void myStackFree(MyStack* obj)
{//结构体指针下创建了两个列表,需要先释放列表QueueDestroy(&obj->q1);QueueDestroy(&obj->q2);free(obj);
}/*** Your MyStack struct will be instantiated and called as such:* MyStack* obj = myStackCreate();* myStackPush(obj, x);* int param_2 = myStackPop(obj);* int param_3 = myStackTop(obj);* bool param_4 = myStackEmpty(obj);* myStackFree(obj);
*/
232. 用栈实现队列 - 力扣(LeetCode)
栈的特性是先后进先出,队列的特性是先进先出;若想用栈实现先进先出,就需要另创建一个栈,将原栈中的数据倒过去就能够轻松实现。
原栈中的数据倒过去之后,此时插入数据,直接插入到原栈中,用原栈专门用来接收数据,如果再出栈,用一个栈专门出栈,当专门出栈的栈出空之后,再从原栈倒数据过来;而不用每次出栈都把数据倒出去又倒回来,很麻烦。
typedef int STDataType;
//支持动态增长的栈
typedef struct Stack
{STDataType* a;int top;//栈顶int capacity;//容量
}ST;// 初始化栈
void STInit(ST* ps);
// 入栈
void STPush(ST* ps, STDataType x);
// 出栈
void STPop(ST* ps);
// 获取栈顶元素
STDataType STTop(ST* ps);
// 获取栈中有效元素个数
int STSize(ST* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);
// 销毁栈
void STDestroy(ST* ps);void STInit(ST* ps)
{assert(ps);ps->a = NULL;ps->capacity = 0;ps->top = 0;
}void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->top = ps->capacity = 0;
}void STPush(ST* ps, STDataType x)
{assert(ps);// 11:40if (ps->top == ps->capacity){int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}ps->a = tmp;ps->capacity = newCapacity;}ps->a[ps->top] = x;ps->top++;
}void STPop(ST* ps)
{assert(ps);// assert(ps->top > 0);--ps->top;
}STDataType STTop(ST* ps)
{assert(ps);// assert(ps->top > 0);return ps->a[ps->top - 1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//定义两个栈类型
typedef struct {ST pushst;ST popst;
} MyQueue;//开辟并初始化结构体变量
MyQueue* myQueueCreate() {MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));STInit(&obj->pushst);STInit(&obj->popst);return obj;
}void myQueuePush(MyQueue* obj, int x) {//始终往push栈上面pushSTPush(&obj->pushst,x);
}
//出队列
int myQueuePop(MyQueue* obj) {int front=myQueuePeek(obj);//与peek唯一不同之处就是取得队头后删掉STPop(&obj->popst);return front;
}
//取队头数据
int myQueuePeek(MyQueue* obj) {if(STEmpty(&obj->popst)){//pop为空,从push倒数据while(!STEmpty(&obj->pushst)){//pop入一个STPush(&obj->popst,STTop(&obj->pushst));//push出一个STPop(&obj->pushst);}}//不为空,直出return STTop(&obj->popst);
}bool myQueueEmpty(MyQueue* obj) {//两个栈都为空才为空return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}void myQueueFree(MyQueue* obj) {STDestroy(&obj->pushst);STDestroy(&obj->popst);free(obj);
}/*** Your MyQueue struct will be instantiated and called as such:* MyQueue* obj = myQueueCreate();* myQueuePush(obj, x);* int param_2 = myQueuePop(obj);* int param_3 = myQueuePeek(obj);* bool param_4 = myQueueEmpty(obj);* myQueueFree(obj);
*/
622. 设计循环队列 - 力扣(LeetCode)
我们用数组来实现,给数组多开一个 rear 空间(不存数据)用来解决探空和探满的问题
front 为列表头节点的下标,rear 为为尾节点的下一个节点的下标;front 和rear 初始值为0,push 一次 rear ++一次,由于列表是定长的,因此当push 了k个数据时,列表就放满了,不能再入数据。放满的标志为此时列表的实际长度(包括 rear节点)对理论长度 k+1 取余的结果等于 front 。
pop操作,我们直接让 front ++,遵循先进先出的原则。
push 操作,push 一次,rear 向后移动一次,直到 rear 的下一个为 front ,则代表放满,标志依然为(rear+1)%(k+1)=front ,当rear<k,就等于 rear +1= front。
此时再 pop 到 front 处于数组末尾,继续 pop,front 就转到数组开头,当 rear 和 front 重合且为空时,数组就为空。
//定义队列
typedef struct {//数组int *a;//头int front;//尾int rear;//数组长度(不包含rear)int k;
} MyCircularQueue;
//初始化队列
MyCircularQueue* myCircularQueueCreate(int k) {//为队列开空间MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//为数组开空间,多开一个rear用于探空(满)obj->a=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->rear=0;obj->k=k;return obj;
}
//探空(非0为空,0为非空)
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {//front和rear相等就是空return obj->front==obj->rear;}
//探满(非0为满,0为未满)
bool myCircularQueueIsFull(MyCircularQueue* obj) {//rear的下一个为front为满;rear在队尾,front在对头为满。return (obj->rear+1)%(obj->k+1)==obj->front;}
//插入
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {//先探满if(myCircularQueueIsFull(obj)){return false;}//正常情况下往rear位置放数据,放完后移obj->a[obj->rear]=value;obj->rear++;//如果rear走到队尾之后(++之后等于k),那么++之后应该挪到队头(归0,因此取模)//取模操作在走过队尾之前无效obj->rear%=(obj->k+1);return true;
}
//删除
bool myCircularQueueDeQueue(MyCircularQueue* obj) {//先探空if(myCircularQueueIsEmpty(obj)){return false;}//正常情况下front后移obj->front++;//如果front走到队尾之后(++之后等于k),那么++之后应该挪到队头(归0,因此取模)obj->front%=(obj->k+1);return true;
}
//取头
int myCircularQueueFront(MyCircularQueue* obj) {//探空if(myCircularQueueIsEmpty(obj)){return -1;}else{return obj->a[obj->front];}
}
//取尾(取rear的上一个节点)
int myCircularQueueRear(MyCircularQueue* obj) {//探空if(myCircularQueueIsEmpty(obj)){return -1;}else{//+k并对k+1取余,当rear在队头,上一个节点就在队尾//不在队头时取余结果刚好为上一个节点return obj->a[(obj->rear+obj->k)%(obj->k+1)];}}void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);}/*** Your MyCircularQueue struct will be instantiated and called as such:* MyCircularQueue* obj = myCircularQueueCreate(k);* bool param_1 = myCircularQueueEnQueue(obj, value);* bool param_2 = myCircularQueueDeQueue(obj);* int param_3 = myCircularQueueFront(obj);* int param_4 = myCircularQueueRear(obj);* bool param_5 = myCircularQueueIsEmpty(obj);* bool param_6 = myCircularQueueIsFull(obj);* myCircularQueueFree(obj);
*/
相关文章:

队列(8.6)
目录 2.队列 2.1队列的概念及结构 2.2队列的实现 2.2.1初始化队列 2.2.2队尾入队列 2.2.3队头出队列 2.2.4获取队列头部元素 2.2.5 销毁队列 3.栈和队列面试题 225. 用队列实现栈 - 力扣(LeetCode) 232. 用栈实现队列 - 力扣(LeetC…...

计算机网络 第四章网络层
文章目录 1 网络层的功能2 数据交换方式:电路交换3 数据交换方式:报文交换4 数据交换方式:分组交换5 数据交换方式:数据报方式6 数据交换方式:虚电路方式及各种方式对比7 路由算法及路由协议8 IP数据报的概念和格式9 I…...

操作系统运行机制
文章目录 操作系统运行机制特权指令VS非特权指令内核态VS用户态中断和异常内中断(异常)外中断中断机制基本原理中断处理过程 系统调用系统调用和库函数的区别为什系统调用时必须的?什么功能需要用到系统调用系统调用的过程小结 操作系统内核 操作系统运行机制 特权…...

mathtype7.4破解永久激活码
MathType(数学公式编辑器)是由Design Science公司研发的一款专业的数学公式编辑工具。MathType功能非常强大,尤其适用于专门研究数学领域的人群使用。使用MathType让你在输入数学公式的时候能够更加的得心应手,各种复杂的运算符号也不在话下。 MathType最…...

66 内网安全-域横向批量atschtasksimpacket
目录 演示案例:横向渗透明文传递at&schtasks 案例2-横向渗透明文HASH传递atexec-impacket案例3-横向渗透明文HASH传递批量利用-综合案例5-探针主机域控架构服务操作演示 传递攻击是建立在明文和hash值的一个获取基础上的攻击,也是在内网里面常见协议的攻击&…...

PCI9054入门1:硬件引脚定义、时序、FPGA端驱动源码
文章目录 1:PCI9054的FPGA侧(local侧引脚定义)2:PCI9054的C模式下的读写时序3:FPGA代码部分具体代码: 1:PCI9054的FPGA侧(local侧引脚定义) 而PCI9054的本地总线端的主要…...

多媒体应用设计师 第17章 多媒体应用场景的技术应用和实现示例
口诀 思维导图 2020...
react151618刷新几次的问题
结论: 16 hooks版本 默认render1次 同步中,无论多少种类还是次数,都render 1次。 异步中,无论多少种类还是次数,1个种类执行1次,多次的话,用n*2。 18 hooks版本 默认render2次, 同步…...

【Spring】IOC容器与Bean的常用属性配置
文章目录 1.前言2.IOC容器2.1 BeanFactory 容器2.2 ApplicationContext 容器 3.Bean的常用属性配置4. 总结 1.前言 在之前的文章-IOC的快速入门中讲过Bean这个概念. 本来就来介绍容器与Bean的常用属性配置 在Spring框架中,Bean指的是被Spring加载生成出来的对象。 …...

2023年下半年 系统集成项目管理工程师 真题考点(一二三四批次)(10月28、29)(网友回忆版)
文章目录 第一批部分考点整体管理采购管理风险管理二:EAC 第二批部分考点如下: 第三批部分考点如下: 第一批 部分考点 1、案例考了关键路径和工期,风险管理、采购、风险、招投标,整体管理。 2、计算题有关键路径和挣…...
读韩都衣舍,谈权力转移的激励制度
这是一个很久之前的商业案例。 在大公司,管理过于复杂,成了现在公司管理的大问题。大公司的流程长,市场的突击速度慢,以及员工的积极性差,成为大公司的一个潜在的弊病。而最近,从韩都衣舍的创始人赵迎光的…...

私有云:【10】VCenter安装win10
私有云:【10】VCenter安装win10 1、ESXI挂载win10镜像2、VCenter安装win102.1、创建虚拟机2.2、启动虚拟机 此WIN10用来作为以后的远程桌面 1、ESXI挂载win10镜像 2、VCenter安装win10 2.1、创建虚拟机 创建虚拟机 设置名称下一步 选择计算机资源 选择NFS存储 设置…...

[Java/力扣100]判断两棵二叉树是否相同
我希望通过这道题,能进一步了解递归思想和“树是递归定义的”这句话 分析 我们的目的是写一个方法来检验两棵树是否相同 什么叫“两棵树相同”?——相同的位置存在相同的结点 有三种情况:1、两棵树一颗为空一颗不为空——不相同ÿ…...
BEC商务英语主题 定价策略|柯桥学商务英语口语
Factors in Pricing Decisions 影响价格制定的因素 A firm cannot determine a product’s price without considering several factors that affect price. 在制定产品价格时,公司如果不考虑影响价格的各种因素是无法制定的。 Managers must take into account t…...
第七章 ObjectScript 一般系统限制
文章目录 第七章 ObjectScript 一般系统限制 字符串长度限制下标限制Global的最大长度 第七章 ObjectScript 一般系统限制 字符串长度限制 字符串的长度有限制:3,641,144 个字符。 重要的是要认识到字符串不仅仅是从输入/输出设备读取的结果。它们可以显示在其他上…...

【Python百练——第1练】使用Python求100以内的所有偶数
作者:Insist-- 个人主页:insist--个人主页 作者简介:梦想从未散场,传奇永不落幕,持续更新优质网络知识、Python知识、Linux知识以及各种小技巧,愿你我共同在CSDN进步 欢迎点赞👍收藏Ὄ…...

springboot心理咨询管理系统
springboot心理咨询管理系统,java心理咨询管理系统,心理咨询管理系统 运行环境: JAVA版本:JDK1.8 IDE类型:IDEA、Eclipse都可运行 数据库类型:MySql(8.x版本都可) 硬件环境…...
Java-API简析_java.net.URL类(基于 Latest JDK)(浅析源码)
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/134024288 出自【进步*于辰的博客】 因为我发现目前,我对Java-API的学习意识比较薄弱…...

C语言浮点型在内存中的存储
目录 前言: 引言: 浮点数存储规则 举个栗子: TIP: 单精度浮点数存储的模型(float) 双精度浮点数存储的模型(double) IEEE对 M 的特殊规定 IEEE对 E 的特殊规定 小试牛刀 先…...
elementPlus | el-tabs 标签管理路由页面
<script setup> import { useRouter } from vue-router const router useRouter()const tabClick (tab)>{const idx tab.indexif(idx 0){router.push(/)}... } </script> <template><!-- 撑开 stretch"true" --><el-tabs type&quo…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
FTXUI::Dom 模块
DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...
Qt学习及使用_第1部分_认识Qt---Qt开发基本流程
前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...
Ansible+Zabbix-agent2快速实现对多主机监控
ansible Ansible 是一款开源的自动化工具,用于配置管理(Configuration Management)、应用部署(Application Deployment)、任务自动化(Task Automation)和编排(Orchestration…...