排序类算法

目录

一、交换类排序

1.冒泡排序

2.快速排序

二、 插入排序

1.直接插入排序

2.折半插入排序

3.希尔排序

三、选择排序

1.简单选择排序

2.堆排序

 完整代码

四、归并排序

 完整代码

五、汇总

六、OJ练习 

        1.冒泡排序:正确表示前一个数和后一个数   

2.选择、堆、归并

完整代码 


一、交换类排序

1.冒泡排序

演示地址:

Comparison Sorting Visualization

 注意:n个数

1.交换条件 如果从小到大排列那么  判断 大数在前就发生交换

2.注意外层循环控制趟数 i从0 到  n-1趟    i++

3.注意内层循环控制遍历着进行交换  从后往前 n-1  到   i   j不能取0因为里面有j-1   j--

4.注意flag是看是否进行交换  经过一趟后没有发生交换则序列本身有序

#include <stdio.h>void BubbleSort(int A[10],int n);void swap(int &a,int &b){int temp=a;a=b;b=temp;
}int main() {int A[10]={9,7,8,6,5,4,3,2,1,0};BubbleSort(A,10);for (int i = 0; i < 10; ++i) {printf("%2d",A[i]);}return 0;
}void BubbleSort(int A[10],int n) {//控制趟数for (int i = 0; i < n - 1; ++i) {//交换标志bool flag= false;//控制交换for (int j = n-1; j > i; j--) {//从小到大排列 大的在前那么就要发生交换了if (A[j-1]>A[j]){swap(A[j],A[j-1]);flag= true;}}if (!flag){//如果经过依次检查后没有发生交换则该数组本身有序return;}}
}

2.快速排序

注意:分治思想

        挖坑法(不断覆盖)得到分隔值的位置

        注意每次循环都要判断   low<high

        注意出现相等的数我们不用管--不需要处理

        最终low与high是相等的

演示地址:

Comparison Sorting Visualization

16.5 快速排序 

64, 94, 95, 79, 69, 84, 18, 22, 12 ,78

把比64小的放在64的左边,把比64大的放在它的右边
18, 22, 12 64  ,94, 95, 79, 69, 84,78

16.6 快速排序实战
原来的
64, 94, 95, 79, 69, 84, 18, 22, 12 ,78


pivot=64
12, 22, 18, 64, 69, 84, 79, 95, 94 ,78
                 high
                 low
pivot=64
12, 94, 95, 79, 69, 84, 18, 22, 12 ,78
                                               high
     low
 

#include <stdio.h>//得到分割值的位置--挖坑法(不断覆盖)
int getPosition(int A[],int low,int high){//把low的位置作为分隔值int provt=A[low];while (low<high){//从high往前找比分隔值小的数的位置--注意循环里面也要判断low<highwhile (low<high&&A[high]>=provt){//没有找到就往前移动high--;}//出循环 这时A[high]<provt  就找到了 这个小的元素//我们需要把它覆盖到low的位置上A[low]=A[high];//从low往后找 直到找到比分隔值大的元素--注意循环里面也要判断low<highwhile (low<high&&A[low]<=provt){low++;}//此时A[low]>provt 找到了大的元素我们需要把它放到分割值的右边//因此我们需要把它覆盖到high的位置上A[high]=A[low];}//不要忘记把分隔值赋值上去A[low]=provt;//此时low=high的return low;
}//快速排序--分治思想
void quickSort(int A[],int low,int high){if (low>=high){return;}//进行第一次快速排序得到分隔值的位置int position=getPosition(A,low,high);//接下来排列分隔值的左边quickSort(A,low,position-1);//接下来排列分隔值的右边quickSort(A,position+1,high);
}

二、 插入排序

1.直接插入排序

注意:

        外层循环控制:无序序列的个数--即要插入的元素个数  i从 1到len-1

        内层循环控制交换 注意条件 

        此时j的位置是从i-1开始 j>=0&&A[j]>inserVal 那么就将后面的元素进行覆盖

        注意最后要将j+1的位置即为要插入的位置

        因为循环完成后我们直到j这个位置是小于inserVal的所以要插入到这个位置的后面

16.7 插入排序的原理及实战

insertVal=1
                           i
    1 2 3 72 78      87 61 38 12 40
 j

//玩坑法(覆盖)  插入排序
void insertSort(int A[],int len){int i,j,inserVal;//注意循环起始  此时有序数列中左半边为1个元素  所以无序的右半边从 1开始到len-1for (i = 1; i < len; ++i) {//外层循环控制要插入的数量//存储当前要插入的值inserVal=A[i];//那么我们判断就从有序的开始  i-1  到0--并且这个元素大于要插入的元素那么就进行覆盖for (j = i-1; j >=0&&A[j]>inserVal ; j--) {//就将后面的元素覆盖成大的那一个A[j+1]=A[j];}//最终要将插入元素进行插入-这里要使用到j因此要将j定义到循环外面//如果最终j--到0了 那么此时将j+1的位置也就是0的位置即插入位置A[j+1]=inserVal;}
}

2.折半插入排序

3.希尔排序

三、选择排序

1.简单选择排序

注意:

         内层循环:

        找到那么就记录该位置--必须写在这  因为我们要把后续的位置找全  找出最小如果写在循环条件处那么 它就会找到一个就交换一次  而不是最小才交换  注意最小条件

//简单选择排序
void selectSort(int A[],int len){int min;for (int i = 0; i < len - 1; ++i) {//外层循环控制趟数//每次都找出一个最小的 交换那么  只需要找len-1次//记录最小值位置min=i;//内层循环从未确定的序列中找最小的位置 因此从i+1开始到结束for (int j = i+1; j < len; ++j) {//找到那么就记录该位置--必须写在这  因为我们要把后续的位置找全  找出最小//如果写在循环条件处那么 它就会找到一个就交换一次  而不是最小才交换  注意最小条件if (A[j]<A[min]){min=j;}}//进行交换swap(A[min],A[i]);}
}

2.堆排序


演示地址:Heap Sort Visualization

每次调整大根堆的时间复杂度为树的高度  调整n次  因此为n*logn

 

 

 注意:

        1.循环调整子树为大根堆的循环条件(son<len)--注意调整完后要重置dad与son

           因为这颗子树可能下面还有子树 

           我们需要让dad=son的 son=2*dad+1 这这颗子树也满足大根堆依次往复

        2.注意len是代表什么

        3.注意建立大根堆的循环条件  i是从最后一个父节点开始到0

        4.注意循环剩余元素为大根堆的循环条件 

        i代表无序的个数 i从len-1到1 直到调整到剩余俩个元素

 

 

//交换
void swap(int &a,int &b){int temp=a;a=b;b=temp;
}/*** 调整一个子树为大根堆* @param A* @param dad 最后一个节点的父节点位置* @param len 需要调整的长度*/
void adjustMaxTree(int A[],int last,int len){int dad=last;int son=2*dad+1;while (son<len){if (son+1<len&&A[son]<A[son+1]){//比较左 右 孩子中最大的元素//如果左孩子 小于 右孩子--最大元素为右孩子son++;//拿右孩子}//得到最大元素为A[son]if (A[son]>A[dad]){//如果孩子大于父亲 交换//将孩子中最大的放到根节点上swap(A[son],A[dad]);//重置父子节点位置dad=son;//son重新作为dad去验证下面的子树是否为大根堆--son=2*dad+1;//继续循环重新进行调整我们交换完的下面的那颗子树是否满足大根堆} else{//这个子树中的所有的子树全部满足大根堆break;}}
}//堆排序
void heapSort(int A[],int len){//建立大根堆for (int i = len/2-1; i >= 0; i--) {//从最后一个子树的父亲节点开始到0adjustMaxTree(A,i,len);}//将最大元素放到数组末尾swap(A[0],A[len-1]);//调整剩余元素为大根堆并从小到大排列--调整到只剩2个元素for (int i = len-1; i > 1; i--) {//i代表的是无序的个数//因为把最大的元素放到了最后一个树节点上 那么每次都要调整 父亲节点地址为0 长度为 i的元素为大跟堆adjustMaxTree(A,0,i);//调整之后进行交换--交换根部元素swap(A[0],A[i-1]);}
}

 完整代码

#include <stdio.h>//交换
void swap(int &a,int &b){int temp=a;a=b;b=temp;
}/*** 调整一个子树为大根堆* @param A* @param dad 最后一个节点的父节点位置* @param len 需要调整的长度*/
void adjustMaxTree(int A[],int last,int len){int dad=last;int son=2*dad+1;while (son<len){if (son+1<len&&A[son]<A[son+1]){//比较左 右 孩子中最大的元素//如果左孩子 小于 右孩子--最大元素为右孩子son++;//拿右孩子}//得到最大元素为A[son]if (A[son]>A[dad]){//如果孩子大于父亲 交换//将孩子中最大的放到根节点上swap(A[son],A[dad]);//重置父子节点位置dad=son;//son重新作为dad去验证下面的子树是否为大根堆--son=2*dad+1;//继续循环重新进行调整我们交换完的下面的那颗子树是否满足大根堆} else{//这个子树中的所有的子树全部满足大根堆break;}}
}//堆排序
void heapSort(int A[],int len){//建立大根堆for (int i = len/2-1; i >= 0; i--) {//从最后一个子树的父亲节点开始到0adjustMaxTree(A,i,len);}//将最大元素放到数组末尾swap(A[0],A[len-1]);//调整剩余元素为大根堆并从小到大排列--调整到只剩2个元素for (int i = len-1; i > 1; i--) {//i代表的是无序的个数//因为把最大的元素放到了最后一个树节点上 那么每次都要调整 父亲节点地址为0 长度为 i的元素为大跟堆adjustMaxTree(A,0,i);//调整之后进行交换--交换根部元素swap(A[0],A[i-1]);}
}int main() {int A[10]={58,42,13,58,44,53,73,75,2,69};int len=10;heapSort(A,len);for (int i = 0; i < 10; ++i) {printf("%3d",A[i]);}return 0;
}

四、归并排序

注意:

        1.复制临时数组  static int B[N];

        2.复制的时候for循环从low开始  避免覆盖掉之前的元素

        3.合并的时候  注意合并的那个数组A  k是从low开始  避免覆盖掉之间的元素

        4.不要忘记 剩余元素的合并

#define N 50void merge(int A[],int low,int mid,int high){//注意static无论递归多少次都只有一个Bstatic int  B[N];//复制临时数组--注意这里是low 到highfor (int i = low; i <= high; ++i) {B[i]=A[i];}int i,j,k;//注意k是从low开始for ( i = low,j=mid+1,k=low;i<=mid&&j<=high; k++) {//i j 的元素值进行比较 小的放入A中--并且放入的元素的那个向后移动if (B[i]<B[j]){A[k]=B[i++];} else{A[k]=B[j++];}}//看哪个有剩余都放入到A中即可while (i<=mid){A[k++]=B[i++];}while (j<=high){A[k++]=B[j++];}
}void mergeSort(int A[],int low,int high){if (low<high){int mid=(low+high)/2;//排序前半边mergeSort(A,low,mid);//排序号后半边mergeSort(A,mid+1,high);//合并为有序数组merge(A,low,mid,high);}
}

 完整代码

#include <stdio.h>#define N 50void merge(int A[],int low,int mid,int high){//注意static无论递归多少次都只有一个Bstatic int  B[N];//复制临时数组--注意这里是low 到highfor (int i = low; i <= high; ++i) {B[i]=A[i];}int i,j,k;//注意k是从low开始for ( i = low,j=mid+1,k=low;i<=mid&&j<=high; k++) {//i j 的元素值进行比较 小的放入A中--并且放入的元素的那个向后移动if (B[i]<B[j]){A[k]=B[i++];} else{A[k]=B[j++];}}//看哪个有剩余都放入到A中即可while (i<=mid){A[k++]=B[i++];}while (j<=high){A[k++]=B[j++];}
}void mergeSort(int A[],int low,int high){if (low<high){int mid=(low+high)/2;//排序前半边mergeSort(A,low,mid);//排序号后半边mergeSort(A,mid+1,high);//合并为有序数组merge(A,low,mid,high);}
}int main() {int A[10]={58,42,13,58,44,53,73,75,2,69};int low=0,high=9;mergeSort(A,low,high);for (int i = 0; i <10; ++i) {printf("%3d",A[i]);}return 0;
}

五、汇总

六、OJ练习 

注意:

        1.冒泡排序:正确表示前一个数和后一个数   

        j--

#include <stdio.h>//读取10个整型数据12 63 58 95 41 35 65  0 38 44,
// 然后通过冒泡排序,快速排序,插入排序,分别对该组数据进行排序,输出3次有序结果,每个数的输出占3个空格//交换
void swap(int &a,int &b){int temp=a;a=b;b=temp;
}void print_A(int A[],int len){//排序完成for (int i = 0; i < len; ++i) {printf("%3d",A[i]);}printf("\n");
}//冒泡排序
void BubbleSort(int A[],int len){bool flag= false;for (int i = 0; i < len ; ++i) {for (int j = len-1; j > i; j--) {//从小到大 如果前面比后面大交换if (A[j-1]>A[j]){swap(A[j-1],A[j]);flag= true;}}if (!flag){return;}}print_A(A,len);
}//挖坑法--分割
int patition(int A[],int low,int high){//先将low的位置作为分割值int provt=A[low];while (low<high){//从后往前找比分隔值小的数进行覆盖while (low<high&&A[high]>=provt){high--;}//此时A[high]<provtA[low]=A[high];//从前往后找比分隔值大数进行覆盖while (low<high&&A[low]<=provt){low++;}//此时A[low]>provtA[high]=A[low];}//填入分隔值A[low]=provt;return low;
}//快速排序--分治
void quickSort(int A[],int low,int high){if (low>high){return;}//确定一个分割位置int position=patition(A,low,high);//排序左边quickSort(A,low,position-1);//排序右边quickSort(A,position+1,high);
}//插入排序
void inserSort(int A[],int len){int i,j,insertVal;for (i = 1; i < len; ++i) {insertVal=A[i];for (j = i-1; j >=0&&A[j]>insertVal; j--) {//交换A[j+1]=A[j];}//插入A[j+1]=insertVal;}print_A(A,len);
}int main() {int A[10];for (int i = 0; i < 10; ++i) {int x;scanf("%d",&x);A[i]=x;}int len=10;BubbleSort(A,len);quickSort(A,0,len-1);print_A(A,len);inserSort(A,len);return 0;
}

2.选择、堆、归并

选择排序:注意  找到最小的后是交换 而不是覆盖

堆排序:  注意第一次建立完大根堆后  将根节点(最大)与最后一个节点进行交换

                然后再依次进行 大根堆的建立 建立的时候 因为最后都改变了根节点与最后一个元                  素的值  那么每次建立大根堆的父节点都是从0开始  注意起始条件

归并排序:注意不要忘记剩余节点也要合为一个数组

//交换
void swap(int &a,int &b){int temp=a;a=b;b=temp;
}//选择排序--找最小的放到前面/找最大的放到后面
void SelectSort(int A[],int len){int i=0,min,j;int temp=A[i];while (i<len){min=i;for (j = i+1; j < len; ++j) {if (A[min]>A[j]){min=j;}}//找到了最小值swap(A[i++],A[min]);}
}//建立大根堆
void buildMaxTree(int A[],int last,int len){int dad=last;int son=last*2+1;while (son<len){if (son+1<len&&A[son]<A[son+1]){son++;//拿到右孩子作为最大}//最大的孩子节点值与父节点比较替换if (A[son]>A[dad]){swap(A[son],A[dad]);//重置dad与son 为下一个子树dad=son;son=2*dad+1;} else{//全部变为大根堆 没有任何交换后--退出循环break;}}
}//堆排序
void heapSort(int A[],int len){//对于初始数组建立大根堆for (int i = len/2-1; i >= 0; i--) {buildMaxTree(A,i,len);}//之后交换根节点与最后一个节点swap(A[0],A[len-1]);//堆剩余元素进行大根堆的依次建立--直到仅剩余2个节点for (int i = len-1; i >1 ; i--) {//i为当今剩余的无序节点数量//因为交换了 那么改变的就是A[0]节点开始 的大根堆--因此此时父节点为0buildMaxTree(A,0,i);//交换改变swap(A[0],A[i-1]);//继续上述操作}
}
//归并排序--合并有序数组
void merge(int A[],int low,int mid,int high){static int B[N];for (int i = low; i <= high; ++i) {B[i]=A[i];}int i,j,k;for (i = low,j=mid+1,k=low;i<=mid&&j<=high; k++) {if (B[i]<B[j]){A[k]=B[i++];} else{A[k]=B[j++];}}//不要忘记还有剩余元素while (i<=mid){A[k++]=B[i++];}while (j<=high){A[k++]=B[j++];}
}
//归并排序
void mergeSort(int A[],int low,int high){if (low>=high){return;}int mid=(low+high)/2;//归并前半部分mergeSort(A,low,mid);//归并后半部分mergeSort(A,mid+1,high);//合并为有序数列merge(A,low, mid,high);
}void printSort(int A[],int len){for (int i = 0; i < len; ++i) {printf("%3d",A[i]);}
}

完整代码 

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

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

相关文章

LLM推理框架Triton Inference Server学习笔记(一): Triton Inference Server整体架构初识

官方文档查阅: TritonInferenceServer文档 1. 写在前面 这篇文章开始进行大语言模型(Large Language Model, LLM)的学习笔记整理&#xff0c;这次想从Triton Inference Server框架开始&#xff0c;因为最近工作上用到了一些大模型部署方面的知识&#xff0c; 所以就快速补充了…

【STM32】串口助手接受数据是乱码如何解决

第一步 首先判断自己使用的串口助手和工程配置的波特率是否相同&#xff0c;一般都是115200 第二步 如果不是上一条的问题&#xff0c;继续排查&#xff0c;检查时钟问题 打开工程&#xff0c;找到此文件(stm32f10x.h)的这个位置&#xff0c;如工程中未添加&#xff0c;可以从…

centos安装hadoop启动问题解决方案

1、出现了问题localhost: ERROR: JAVA_HOME is not set and could not be found. *解决方案尝试&#xff1a; 修改hadoop-env.sh&#xff08;在etc/hadoop&#xff09; sudo gedit /usr/local/hadoop/etc/hadoop/hadoop-env.sh 将原本的JAVA_HOME 替换为绝对路径就可以了 #expo…

Leetcode 144. 二叉树的前序遍历

题目描述&#xff1a;给定一个二叉树的根节点 root &#xff0c;返回 它的 前序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&…

关于C语言调用Python,PyImport_ImportModule函数的简介

函数原型&#xff1a;PyObject *PyImport_ImportModule(const char *name) 用于加载编译目标的文件 这个模块必须为.py文件&#xff0c;因为说直白点就是通过Python3 xxxx.py能够通过编译的东西

项目管理【引论二】项目管理的逻辑

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 一、项目管理的目标 项目管理的目标是在规定的时间内&#xff0c;在批准的预算内&#xff0c;完成事先确定的工作范围内的工作&#xff0c;并且达到预期的质量性能要求。 1.1 时间、成本和质量之间的关系 1…

力扣226.翻转二叉树(二叉树的先序遍历)

文章目录 题目描述思路复杂度Code 题目描述 思路 利用二叉树的先序遍历&#xff0c;每次递归遍历时将当前节点的左右子节点交换即可 复杂度 时间复杂度: O ( n ) O(n) O(n)&#xff1b;其中 n n n为树节点的个数 空间复杂度: O ( h e i g h ) O(heigh) O(heigh)&#xff1b;其…

嵌入式学习第二十七天!(TCP并发模型)

TCP并发模型&#xff1a; 1. TCP多线程模型&#xff1a; 缺点&#xff1a;创建线程会带来资源开销&#xff0c;能够实现的并发量比较有限。 2. IO模型&#xff1a; 1. 阻塞IO&#xff1a; 没有数据到来时&#xff0c;可以让任务挂起&#xff0c;节省CPU资源开销&#xff0c;提…

案例分析篇01:软件架构设计考点架构风格及质量属性(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12601310.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

【SpringCloud微服务实战01】Eureka 注册中心

前言 在 Eureka 架构中,微服务角色有两类: EurekaServer :服务端,注册中心 记录服务信息 心跳监控 EurekaClient :客户端 Provider :服务提供者,例如案例中的 user-service 注册自己的信息到 EurekaS…

解决vue项目,运行npm install安装报缺少c++库问题

项目是前后端分离架构&#xff0c;前端使用的是vue框架&#xff0c;在部署前端项目时&#xff0c;需要下载安装一些基础的镜像配置&#xff0c;包括一些预处理&#xff0c;但是在使用npm install和yarn install命令时出现了如下错误&#xff0c;查阅资料总结如下&#xff1a; …

WPF(2)命令绑定

效果是&#xff1a;当TextBox控件的Text属性为空时show按钮不可用&#xff0c;有值时show按钮可用 项目结构 界面代码 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sc…

Flutter ios一键三连脚本

flutter运行ios时总得执行三个命令,中间还得等待&#xff0c;有没有脚本自动执行 ## ios 执行命令 - flutter clean - flutter pub get - cd ios - pod install有&#xff0c;项目根目录创建shell 文件夹&#xff0c;新建setup.sh setup.sh里面放如下代码 #!/bin/bash# ios …

ffmpeg解码和渲染理解

ffmpeg解码和渲染理解 ffmpeg视频解码步骤 FFmpeg 是一个功能强大的跨平台多媒体处理工具&#xff0c;包含了音视频编解码、封装/解封装、过滤器等功能。下面是一般情况下使用 FFmpeg 进行视频解码的步骤&#xff1a; 初始化 FFmpeg 库&#xff1a;首先需要初始化 FFmpeg 库&a…

【Sql】数据库的三范式?MySQL数据库引擎有?InnoDB与MyISAM的区别

目录 数据库的三范式&#xff1f; MySQL数据库引擎有&#xff1f; InnoDB与MyISAM的区别 数据库的三范式&#xff1f; 第一范式&#xff1a;是数据库最基本的要求&#xff0c;列不可再分 第二范式&#xff1a;行可以唯一区分&#xff0c;主键约束 第三范式&#xff1a;是在…

【深度学习笔记】7_4 动量法momentum

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 7.4 动量法 在7.2节&#xff08;梯度下降和随机梯度下降&#xff09;中我们提到&#xff0c;目标函数有关自变量的梯度代表了目标函数…

【ArcGIS】栅格数据进行标准化(归一化)处理

栅格数据进行标准化&#xff08;归一化&#xff09;处理 方法1&#xff1a;栅格计算器方法2&#xff1a;模糊分析参考 栅格数据进行标准化(归一化)处理 方法1&#xff1a;栅格计算器 栅格计算器&#xff08;Raster Calculator&#xff09; 方法2&#xff1a;模糊分析 空间…

Python实现图片(合并)转PDF

在日常的工作和学习过程当中,我相信很多人遇到过这样一个很普通的需求,就是将某一个图片转为PDF或者是将多个图片合并到一个PDF文件。但是,在苦苦搜寻一圈之后发现要么要下载软件,下载了还要注册,注册了还要VIP,甚至SVIP才能实现这样的需求! 今天,我带大家把这个功能打…

2024年华为HCIA-DATACOM新增题库(H12-811)

801、[单选题]178/832、在系统视图下键入什么命令可以切换到用户视图? A quit B souter C system-view D user-view 试题答案&#xff1a;A 试题解析&#xff1a;在系统视图下键入quit命令退出到用户视图。因此答案选A。 802、[单选题]“网络管理员在三层交换机上创建了V…

Kubernetes | 起源 | 组件详解

起源 起源&#xff1a; Kubernetes&#xff08;常简称为K8s&#xff09;起源于Google内部的Borg项目&#xff0c;是一个开源的容器编排引擎&#xff0c;于2014年首次对外发布。 Google Borg Google Borg 是 Google 内部开发和使用的大规模集群管理系统&#xff0c;用于管理和运…