Spring Boot 集成 Knife4j 的 Swagger 文档

在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j 的 Swagger,以实现 API 文档的自动生成和展示。

官网:Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j

源码:knife4j: Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案

1. UI 界面配置步骤

1.1. 添加依赖

<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version>
</dependency>

1.2. 添加配置文件

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {/*** 该方法的主要作用是通过knife4j生成接口文档,若想要多个分组,则需要配置多个Docket实例** @return Docket 实例,用于Swagger接口文档的配置和生成*/@Beanpublic Docket docket(Environment environment) {// 构建API信息,用于Swagger文档的元数据ApiInfo apiInfo = new ApiInfoBuilder().title("swagger测试项目接口文档") // 设置API的标题.contact(new Contact("zjp", "http://termurl.com", "zjp@email.com")).version("1.0") // 设置API的版本.description("swagger测试项目接口文档") // 设置API的描述信息.termsOfServiceUrl("http://termurl.com") // 设置服务条款URL,非必要.license("Apache 2.0") // 设置API的授权协议,非必要.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0") // 设置授权协议的URL,非必要.build();// 创建Docket实例并进行配置Docket docket = new Docket(DocumentationType.SWAGGER_2) // 指定文档类型为Swagger2。支持SWAGGER_12(1.2版本)、SWAGGER_2(2.0版本)、OAS_30(3.0版本)等。多个实例版本不同会在各个版本中各生成一个文档.enable(environment.acceptsProfiles(Profiles.of("dev", "test"))) // 设置是否启用Swagger,默认为true,也可以通过环境变量或配置文件来动态控制.apiInfo(apiInfo) // 设置API信息.select() // 进入配置选择器// 若需要匹配指定包路径的控制器,可以使用basePackage()方法,可以是包名或类名,支持通配符*;// 若需要匹配所有路径,可以使用any()方法,例如:any();// 若需要匹配指定注解的控制器,可以使用withClassAnnotation()方法,例如:withClassAnnotation(RestController.class);// 若需要匹配指定方法注解的控制器,可以使用withMethodAnnotation()方法,例如:withMethodAnnotation(ApiOperation.class);// 若不需要匹配任何注解的控制器,可以使用none()方法,例如:none();.apis(RequestHandlerSelectors.basePackage("com.zjp.knife4jswaggerdemo.controller"))// 若需要匹配指定类,可以使用any()方法,例如:any();// 若需要匹配指定路径,可以使用ant()方法,例如:ant("/api/**");// 若需要排除某些路径,可以使用ant()方法,例如:ant("!/api/**");// 若需要匹配以指定字符串结尾的路径,可以使用ant()方法,例如:ant("/**/api");// 若需要匹配以指定字符串开头的路径,可以使用regex()方法,例如:regex("/api/.*");// 若不需要匹配任何路径,可以使用none()方法,例如:none().paths(PathSelectors.any()).build() // 结束配置并构建Docket实例.groupName("default"); // 设置分组名称,多个分组名称不能重名
//                .pathMapping("/") // 设置路径映射,用于指定Swagger UI的根路径,默认为/。
//                .protocols(new HashSet<>(Arrays.asList("http", "https"))) // 设置支持的协议
//                .securitySchemes(Collections.singletonList(new ApiKey("token", HttpHeaders.AUTHORIZATION, In.HEADER.toValue()))) // 授权信息设置,必要的header token等认证信息
//                .securityContexts(Collections.singletonList(
//                        SecurityContext.builder()
//                                .securityReferences(Collections.singletonList(new SecurityReference("token", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
//                                .build())); // 设置全局安全上下文,用于指定全局的授权信息return docket;}/*** 该方法的主要作用是通过knife4j生成接口文档,若想要多个分组,则需要配置多个Docket实例* 例如配置第二个Docket实例,分组名称为api** @return Docket 实例,用于Swagger接口文档的配置和生成*/@Beanpublic Docket docket1() {// 构建API信息,用于Swagger文档的元数据ApiInfo apiInfo = new ApiInfoBuilder().title("swagger测试项目接口文档").version("1.0").description("swagger测试项目接口文档").build();// 创建Docket实例并进行配置Docket docket = new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo) // 设置API信息.select() // 进入配置选择器.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)).paths(PathSelectors.ant("/api/**")).build().groupName("api");return docket;}/*** 该方法用于在Spring MVC中配置静态资源的访问路径和位置* 它通过ResourceHandlerRegistry对象来注册资源处理器,* 从而使得特定URL路径下的请求能够映射到应用程序的静态资源上** @param registry ResourceHandlerRegistry实例,用于注册资源处理器*/protected void addResourceHandlers(ResourceHandlerRegistry registry) {// 映射/doc.html到classpath:/META-INF/resources/,以便访问该路径时能够获取到相应的静态文件registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");// 映射/webjars/**到classpath:/META-INF/resources/webjars/,用于支持webjars资源的访问registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}
}

1.3. 启动测试

浏览器访问 http://localhost:8080/doc.html ,访问结果如下图:

界面说明:

左上角的下拉框对应的分组,如下图所示:

 主页对应的是 ApiInfo 里的信息及 Docket 里的 groupName 。

在文档管理-全局参数设置可以设置全局请求头和参数。 

 

2.  使用swagger

2.1. 常用注解

注解

用途

示例

@Api

标记一个控制器类,描述该类的功能

@Api(value = "用户管理相关接口", tags = {"用户管理"})

@ApiOperation

描述一个 API 接口的方法

@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户信息")

@ApiParam

描述方法参数

@ApiParam(name = "id", value = "用户ID", required = true)

@ApiImplicitParam

描述隐式参数,常用于 GET 请求的查询参数

@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header")

@ApiImplicitParams

描述多个隐式参数

@ApiImplicitParams({

@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header"),

@ApiImplicitParam(name = "page", value = "页码", required = false, dataType = "integer", paramType = "query")

})

@ApiResponse

描述方法的响应信息

@ApiResponse(code = 200, message = "成功返回用户信息")

@ApiResponses

描述多个响应信息

@ApiResponses({

@ApiResponse(code = 200, message = "成功返回用户信息"),

@ApiResponse(code = 404, message = "用户不存在")

})

@ApiModel

描述一个模型类

@ApiModel(description = "用户信息")

@ApiModelProperty

描述模型类的属性

@ApiModelProperty("主键值")

@ApiIgnore

忽略某个方法或类,不生成 API 文档

@ApiIgnore

@ApiExample

描述 API 示例请求

@ApiExample(value = "获取用户信息示例", source = "GET /users/{id}")

2.2. 使用示例

controller层使用示例:

import com.zjp.knife4jswaggerdemo.pojo.User;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@Api(value = "用户管理相关接口", tags = {"用户管理"})
public class UserController {@GetMapping("/getUser")@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户信息")@ApiImplicitParams({@ApiImplicitParam(name = "token", value = "访问令牌", required = true, dataType = "string", paramType = "header"),@ApiImplicitParam(name = "page", value = "页码", required = false, dataType = "integer", paramType = "query")})@ApiResponses({@ApiResponse(code = 200, message = "成功返回用户信息"),@ApiResponse(code = 404, message = "用户不存在")})public User getUser(@ApiParam(name = "id", value = "用户ID", required = true) @RequestParam Integer id) {User user = new User();user.setId(1);user.setName("Alice");user.setAge(18);user.setSex("female");return user;}
}

 实体类使用示例:

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(value = "用户信息", description = "用户信息实体类")
public class User {@ApiModelProperty(value = "主键值", example = "1001")private Integer id;@ApiModelProperty(value = "名称", example = "Bob")private String name;@ApiModelProperty(value = "年龄", example = "32")private Integer age;@ApiModelProperty(value = "性别", example = "male")private String sex;
}

2.3. 启动测试

浏览器访问 http://localhost:8080/doc.html ,访问结果如下图:

实体类信息如下(不调用实体类这里不会展示实体类信息):

 接口文档:

测试接口:

3.  其他配置

属性默认值说明值
knife4j.enablefalse是否开启Knife4j增强模式
knife4j.corsfalse是否开启一个默认的跨域配置,该功能配合自定义Host使用
knife4j.productionfalse是否开启生产环境保护策略,详情参考文档
knife4j.basic对Knife4j提供的资源提供BasicHttp校验,保护文档
knife4j.basic.enablefalse关闭BasicHttp功能
knife4j.basic.usernamebasic用户名
knife4j.basic.passwordbasic密码
knife4j.documents自定义文档集合,该属性是数组
knife4j.documents.group所属分组
knife4j.documents.name类似于接口中的tag,对于自定义文档的分组
knife4j.documents.locationsmarkdown文件路径,可以是一个文件夹(classpath:markdowns/*),也可以是单个文件(classpath:md/sign.md)
knife4j.setting前端Ui的个性化配置属性
knife4j.setting.enable-after-scripttrue调试Tab是否显示AfterScript功能,默认开启
knife4j.setting.languagezh-CNUi默认显示语言,目前主要有两种:中文(zh-CN)、英文(en-US)
knife4j.setting.enable-swagger-modelstrue是否显示界面中SwaggerModel功能
knife4j.setting.swagger-model-nameSwagger Models重命名SwaggerModel名称,默认
knife4j.setting.enable-document-managetrue是否显示界面中"文档管理"功能
knife4j.setting.enable-reload-cache-parameterfalse是否在每个Debug调试栏后显示刷新变量按钮,默认不显示
knife4j.setting.enable-versionfalse是否开启界面中对某接口的版本控制,如果开启,后端变化后Ui界面会存在小蓝点
knife4j.setting.enable-request-cachetrue是否开启请求参数缓存
knife4j.setting.enable-filter-multipart-apisfalse针对RequestMapping的接口请求类型,在不指定参数类型的情况下,如果不过滤,默认会显示7个类型的接口地址参数,如果开启此配置,默认展示一个Post类型的接口地址
knife4j.setting.enable-filter-multipart-api-method-typePOST具体接口的过滤类型
knife4j.setting.enable-hostfalse是否启用Host
knife4j.setting.enable-host-textfalseHOST地址
knife4j.setting.enable-home-customfalse是否开启自定义主页内容
knife4j.setting.home-custom-path主页内容Markdown文件路径
knife4j.setting.enable-searchfalse是否禁用Ui界面中的搜索框
knife4j.setting.enable-footertrue是否显示Footer
knife4j.setting.enable-footer-customfalse是否开启自定义Footer
knife4j.setting.footer-custom-contentfalse自定义Footer内容
knife4j.setting.enable-dynamic-parameterfalse是否开启动态参数调试功能
knife4j.setting.enable-debugtrue启用调试
knife4j.setting.enable-open-apitrue显示OpenAPI规范
knife4j.setting.enable-grouptrue显示服务分组

3.1. 访问权限控制

对应官网原文:3.5 访问权限控制 | Knife4j

3.1.1. 生产环境禁用

目前Springfox-Swagger以及Knife4j提供的资源接口包括如下:

资源说明
/doc.htmlKnife4j提供的文档访问地址
/v2/api-docs-extKnife4j提供的增强接口地址,自2.0.6版本后删除
/swagger-resourcesSpringfox-Swagger提供的分组接口
/v2/api-docsSpringfox-Swagger提供的分组实例详情接口
/swagger-ui.htmlSpringfox-Swagger提供的文档访问地址
/swagger-resources/configuration/uiSpringfox-Swagger提供
/swagger-resources/configuration/securitySpringfox-Swagger提供

 springdoc以及Knife4j提供的资源接口包括如下:

资源说明
/doc.htmlKnife4j提供的文档访问地址
/v3/api-docsspringdoc提供的实例接口
/v3/api-docs/swagger-configspringdoc提供的分组接口
/v3/api-docs/**分组
/swagger-ui/index.htmlspringdoc提供的文档访问地址

当我们部署系统到生产系统,为了接口安全,需要屏蔽所有Swagger的相关资源

如果使用SpringBoot框架,只需在application.properties或者application.yml配置文件中配置:

knife4j:# 开启增强配置 enable: true# 开启生产环境屏蔽production: true

 配置此属性后,所有资源都会屏蔽输出.

效果图如下:

 3.1.2. 登录认证

不管是官方的swagger-ui.html或者doc.html,目前接口访问都是无需权限即可访问接口文档的,很多朋友以前问我能不能提供一个登陆界面的功能,开发者输入用户名和密码来控制界面的访问,只有知道用户名和密码的人才能访问此文档

做登录页控制需要有用户的概念,所以相当长一段时间都没有提供此功能

针对Swagger的资源接口,Knife4j提供了简单的Basic认证功能

效果图如下:

允许开发者在配置文件中配置一个静态的用户名和密码,当对接者访问Swagger页面时,输入此配置的用户名和密码后才能访问Swagger文档页面,如果您使用SpringBoot开发,则只需在相应的application.properties或者application.yml中配置如下:

knife4j:# 开启增强配置 enable: true# 开启Swagger的Basic认证功能,默认是falsebasic:enable: true# Basic认证用户名username: test# Basic认证密码password: 123

如果用户开启了basic认证功能,但是并未配置用户名及密码,Knife4j提供了默认的用户名和密码:

admin/123321

 3.2. 请求参数缓存

在默认情况下,在接口调试的情况下,Knifetj对于接口的请求参数都会缓存起来,该配置可以在前端界面中的个性化设置中看到,如下图:

缓存的情况只会在后端没有给属性example的情况下产生,如果后端在写Swagger的注解的时候,给每个字段赋予了example的值,那么,Knife4j不会使用调试时缓存的值,而是会一直使用后端的example值。

当然,开发者也可以在后端控制文档的接口调试功能,针对请求后的参数是否需要缓存(自2.0.6版本开始)

yml配置如下:

knife4j:enable: truesetting:# 对于调试中的请求参数是否缓存进行开启配置,该参数默认为trueenable-request-cache: true

 也可以手动清理缓存:

 3.3. 动态请求参数

方式一:后台开启

开发者也可以通过开启Knife4j的增强配置,进行默认开启,配置如下:

knife4j:enable: truesetting:# 开启动态请求参数,true-开启,false-关闭enable-dynamic-parameter: true

方式二:界面开启

当在配置中勾选该选项后,我们的接口栏会有变化,如下图:

在原本已存在的参数栏下会出现一栏空的参数栏,开发者可以输入参数名称、参数值对参数进行添加

不管是参数名称的变化还是参数值的变化,变化后会自动追加一行新的调试栏参数,效果图如下:

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

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

相关文章

微信小程序中会议列表页面的前后端实现

题外话&#xff1a;想通过集成腾讯IM来解决即时聊天的问题&#xff0c;如果含语音视频&#xff0c;腾讯组件一年5万起步&#xff0c;贵了&#xff01;后面我们改为自己实现这个功能&#xff0c;这里只是个总结而已。 图文会诊需求 首先是个图文列表界面 同个界面可以查看具体…

git(Linux)

1.git 三板斧 基本准备工作&#xff1a; 把远端仓库拉拉取到本地了 .git --> 本地仓库 git在提交的时候&#xff0c;只会提交变化的部分 就可以在当前目录下新增代码了 test.c 并没有被仓库管理起来 怎么添加&#xff1f; 1.1 git add test.c 也不算完全添加到仓库里面&…

【动手学电机驱动】STM32-FOC(8)MCSDK Profiler 电机参数辨识

STM32-FOC&#xff08;1&#xff09;STM32 电机控制的软件开发环境 STM32-FOC&#xff08;2&#xff09;STM32 导入和创建项目 STM32-FOC&#xff08;3&#xff09;STM32 三路互补 PWM 输出 STM32-FOC&#xff08;4&#xff09;IHM03 电机控制套件介绍 STM32-FOC&#xff08;5&…

5G NR:带宽与采样率的计算

100M 带宽是122.88Mhz sampling rate这是我们都知道的&#xff0c;那它是怎么来的呢&#xff1f; 采样率 子载波间隔 * 采样长度 38.211中对于Tc的定义&#xff0c; 在LTE是定义了Ts&#xff0c;在NR也就是5G定义了Tc。 定义这个单位会对我们以后工作中的计算至关重要。 就是在…

【湿度数据处理】中国地面气候资料日值数据集(V3.0)(MATLAB全代码)

【湿度数据处理】中国地面气候资料日值数据集 处理1:数据范围筛选处理2:缺测数据筛查处理3:缺测数据插补参考基于此博客完成各要素数据提取后-【数据集处理】中国地面气候资料日值数据集(V3.0)(含MATLAB全代码),进行后续数据筛选及缺测处理,此处以湿度数据为例。 提取到的…

MySQL面试-1

InnoDB中ACID的实现 先说一下原子性是怎么实现的。 事务要么失败&#xff0c;要么成功&#xff0c;不能做一半。聪明的InnoDB&#xff0c;在干活儿之前&#xff0c;先将要做的事情记录到一个叫undo log的日志文件中&#xff0c;如果失败了或者主动rollback&#xff0c;就可以通…

大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

leetcode_有序数组中的单一元素

540. 有序数组中的单一元素 - 力扣&#xff08;LeetCode&#xff09; 二分查找 使用条件 &#xff1a; 有序 &#xff0c; log n class Solution { public:int singleNonDuplicate(vector<int>& nums) {int left 0, right nums.size() - 1, mid;while (left <…

Python中的简单爬虫

文章目录 一. 基于FastAPI之Web站点开发1. 基于FastAPI搭建Web服务器2. Web服务器和浏览器的通讯流程3. 浏览器访问Web服务器的通讯流程4. 加载图片资源代码 二. 基于Web请求的FastAPI通用配置1. 目前Web服务器存在问题2. 基于Web请求的FastAPI通用配置 三. Python爬虫介绍1. 什…

USRP:B205mini-i

USRP B205mini-i B205mini-i都是采用工业级的FPGA芯片(-I表示industrial-grade)&#xff0c;所以价格贵。 这个工业级会让工作温度从原来 0 – 45 C 变为 -40 – 75 C. 温度的扩宽&#xff0c;会让工作的稳定性变好。但是前提是你需要配合NI的外壳才行&#xff0c;你如果只买一…

基于Redis内核的热key统计实现方案|得物技术

一、Redis热key介绍 Redis热key问题是指单位时间内&#xff0c;某个特定key的访问量特别高&#xff0c;占用大量的CPU资源&#xff0c;影响其他请求并导致整体性能降低。而且&#xff0c;如果访问热key的命令是时间复杂度较高的命令&#xff0c;会使得CPU消耗变得更加严重&…

鸿蒙安全控件之位置控件简介

位置控件使用直观且易懂的通用标识&#xff0c;让用户明确地知道这是一个获取位置信息的按钮。这满足了授权场景需要匹配用户真实意图的需求。只有当用户主观愿意&#xff0c;并且明确了解使用场景后点击位置控件&#xff0c;应用才会获得临时的授权&#xff0c;获取位置信息并…

鸿蒙主流路由详解

鸿蒙主流路由详解 Navigation Navigation更适合于一次开发,多端部署,也是官方主流推荐的一种路由控制方式,但是,使用起来入侵耦合度高,所以,一般会使用HMRouter,这也是官方主流推荐的路由 Navigation官网地址 个人源码地址 路由跳转 第一步-定义路由栈 Provide(PageInfo) pag…

Jackson库中JsonInclude的使用

简介 JsonInclude是 Jackson 库&#xff08;Java 中用于处理 JSON 数据的流行库&#xff09;中的一个注解。它用于控制在序列化 Java 对象为 JSON 时&#xff0c;哪些属性应该被包含在 JSON 输出中。这个注解提供了多种策略来决定属性的包含与否&#xff0c;帮助减少不必要的数…

88页精品PPT | 某电信集团大数据平台建设方案技术交流

这份PPT文档是关于某电信集团大数据平台建设的技术交流方案&#xff0c;内容涵盖了现状分析、规划思路、产品设计、成功案例以及干货附录等多个部分。文档详细介绍了集团大数据平台的建设背景、技术特点、面临的挑战和痛点&#xff0c;以及具体的技术架构和实施策略。还包括了数…

Java设计模式笔记(一)

Java设计模式笔记&#xff08;一&#xff09; &#xff08;23种设计模式由于篇幅较大分为两篇展示&#xff09; 一、设计模式介绍 1、设计模式的目的 让程序具有更好的&#xff1a; 代码重用性可读性可扩展性可靠性高内聚&#xff0c;低耦合 2、设计模式的七大原则 单一职…

在使用PCA算法进行数据压缩降维时,如何确定最佳维度是一个关键问题?

一、PCA算法的基本原理 PCA算法的核心思想是通过正交变换&#xff0c;将一组可能相关的变量转换成一组线性不相关的变量&#xff0c;称为主成分。这组主成分能够以最小的信息损失来尽可能多地保留原始数据集的变异性。具体来说&#xff0c;PCA算法包括以下几个步骤&#xff1a…

shodan(7)

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

三维地形图计算软件(三)-原基于PYQT5+pyqtgraph旧代码

最先入手设计三维地形图及平基挖填方计算软件时&#xff0c;地形图的显示方案是&#xff1a;三维视图基于pyqtgraph.opengl显示和二维视图基于pyqtgraph的PlotWidget来显示地形地貌&#xff0c;作到一半时就发现&#xff0c;地形点过多时&#xff0c;将会造成系统卡顿(加载时主…

从入门到精通数据结构----四大排序(上)

目录 首言&#xff1a; 1. 插入排序 1.1 直接插入排序 1.2 希尔排序 2. 选择排序 2.1 直接选择排序 2.2 堆排序 3. 交换排序 3.1 冒泡排序 3.2 快排 结尾&#xff1a; 首言&#xff1a; 本篇文章主要介绍常见的四大排序&#xff1a;交换排序、选择排序、插入排序、归并排…