MySQL EXPLAIN实战:6种索引失效场景验证与优化

前置知识:在阅读本文之前,建议先了解EXPLAIN命令的基础知识。如果你还不熟悉EXPLAIN,请先阅读《MySQL EXPLAIN命令详解:SQL查询性能分析与优化指南(基础篇)》。

前言:索引是提升数据库查询性能的重要手段,但并不是所有查询都能有效利用索引。在实际开发中,我们经常遇到索引失效的情况,导致查询性能下降。本文将通过EXPLAIN命令,逐一验证6种常见的索引失效场景,并提供相应的优化建议。

本文将验证以下场景:

  • 场景1:模糊匹配导致索引失效
  • 场景2:函数操作导致索引失效
  • 场景3:表达式计算导致索引失效
  • 场景4:隐式类型转换导致索引失效
  • 场景5:联合索引非最左匹配导致索引失效
  • 场景6:WHERE子句中的OR导致索引失效

一、创建测试表

为了准确验证每个场景,我们采用"按需创建索引"的方式,避免预先创建的索引影响验证结果。

-- 创建员工表(不创建索引,只保留主键)CREATETABLE employees ( id INTPRIMARYKEYAUTO_INCREMENT, name VARCHAR(100), age INT, phone VARCHAR(20), salary DECIMAL(10,2), department_id INT, hire_date DATE);-- 插入测试数据INSERTINTO employees (name, age, phone, salary, department_id, hire_date)VALUES('张三',25,'13800138001',8000.00,1,'2020-01-15'),('李四',30,'13800138002',12000.00,2,'2019-06-20'),('王五',28,'13800138003',9500.00,1,'2021-03-10'),('赵六',35,'13800138004',15000.00,3,'2018-11-05'),('钱七',27,'13800138005',10000.00,2,'2020-08-22'),('张伟',32,'13800138006',13000.00,1,'2019-04-18'),('李娜',29,'13800138007',11000.00,3,'2021-01-30'),('王芳',26,'13800138008',8500.00,2,'2020-12-01'),('赵强',31,'13800138009',14000.00,1,'2018-07-15'),('钱龙',33,'13800138010',16000.00,3,'2017-09-20');-- 查看表结构DESC employees;-- 查看索引(此时只有主键索引)SHOWINDEXFROM employees;

主键索引(Primary Key)

在这里插入图片描述

二、场景1:模糊匹配导致索引失效

2.1 问题分析

问题: 左模糊匹配(LIKE ‘%value’)会导致索引失效

2.2 验证过程

-- 创建name列的索引CREATEINDEX idx_name ON employees(name);-- 1.1 左模糊匹配(索引失效)EXPLAINSELECT*FROM employees WHERE name LIKE'%张';-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 1.2 左右模糊匹配(索引失效)EXPLAINSELECT*FROM employees WHERE name LIKE'%张%';-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 1.3 右模糊匹配(索引生效)EXPLAINSELECT*FROM employees WHERE name LIKE'张%';-- 结果:type = range, key = idx_name(使用索引范围扫描)-- 1.4 精确匹配(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三';-- 结果:type = ref, key = idx_name(使用索引查找)

2.3 结论



分别从左模糊查询和右模糊查询我们可以看出,左模糊查询会导致索引失效,查询使用的是全盘扫描。右模糊查询则是使用到了索引查询。
  • 左模糊(%value)和左右模糊(%value%)会导致索引失效
  • 右模糊(value%)和精确匹配可以使用索引

2.4 优化建议

  • 避免使用左模糊匹配
  • 考虑使用全文索引(FULLTEXT)
  • 使用搜索引擎(如Elasticsearch)

优化示例:

-- 方案1:使用右模糊WHERE name LIKE'张%'-- 方案2:使用全文索引ALTERTABLE employees ADD FULLTEXT INDEX ft_name (name);EXPLAINSELECT*FROM employees WHEREMATCH(name) AGAINST('张'INNATURALLANGUAGEMODE); -- 方案3:使用搜索引擎(如Elasticsearch)-- 适合复杂的全文搜索场景
全文索引

三、场景2:函数操作导致索引失效

3.1 问题分析

问题: 对索引列使用函数会导致索引失效

3.2 验证过程

-- 创建hire_date列的索引CREATEINDEX idx_hire_date ON employees(hire_date);-- 2.1 使用YEAR函数(索引失效)EXPLAINSELECT*FROM employees WHEREYEAR(hire_date)=2020;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 2.2 使用MONTH函数(索引失效)EXPLAINSELECT*FROM employees WHEREMONTH(hire_date)=6;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 2.3 使用UPPER函数(索引失效)EXPLAINSELECT*FROM employees WHERE UPPER(name)='张三';-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 2.4 优化:使用范围查询(索引生效)EXPLAINSELECT*FROM employees WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31';-- 结果:type = range, key = idx_hire_date(使用索引范围扫描)

3.3 结论



对索引使用函数会导致索引失效
  • 对索引列使用函数会破坏索引的有序性,导致索引失效
  • 应将函数操作移到应用层或使用范围查询替代

3.4 优化建议

  • 避免在WHERE子句中对索引列使用函数
  • 将函数操作移到应用层处理
  • 使用计算列或生成列(MySQL 5.7+)

优化示例:

-- 方案1:使用范围查询WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31'-- 方案2:使用计算列(MySQL 5.7+)ALTERTABLE employees ADDCOLUMN hire_year INT GENERATED ALWAYS AS(YEAR(hire_date)) STORED;CREATEINDEX idx_hire_year ON employees(hire_year);WHERE hire_year =2020-- 方案3:应用层处理-- 在应用层计算好年份,然后查询WHERE hire_date >='2020-01-01'AND hire_date <='2020-12-31'

四、场景3:表达式计算导致索引失效

4.1 问题分析

问题: 对索引列进行表达式计算会破坏索引

4.2 验证过程

-- 创建salary和age列的索引CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_age ON employees(age);-- 3.1 索引列参与计算(索引失效)EXPLAINSELECT*FROM employees WHERE salary +1000>10000;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 3.2 索引列参与计算(索引失效)EXPLAINSELECT*FROM employees WHERE age -5>20;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 3.3 索引列参与计算(索引失效)EXPLAINSELECT*FROM employees WHERE salary *1.1>10000;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 3.4 优化:将计算移到右边(索引生效)EXPLAINSELECT*FROM employees WHERE salary >10000-1000;-- 结果:type = range, key = idx_salary(使用索引范围扫描)-- 3.5 优化:直接使用常量(索引生效)EXPLAINSELECT*FROM employees WHERE salary >9000;-- 结果:type = range, key = idx_salary(使用索引范围扫描)

4.3 结论

  • 索引列参与表达式计算会导致索引失效
  • 应将计算移到查询条件的右边或应用层

4.4 优化建议

  • 避免在WHERE子句中对索引列进行计算
  • 将计算移到应用层
  • 使用覆盖索引优化

优化示例:

-- 方案1:将计算移到右边WHERE salary >10000-1000-- 方案2:应用层计算-- 在应用层计算好阈值,然后查询WHERE salary >9000-- 方案3:使用覆盖索引CREATEINDEX idx_salary_bonus ON employees(salary, bonus);WHERE salary + bonus >100000

五、场景4:隐式类型转换导致索引失效

5.1 问题分析

问题: 当查询中数据类型与索引不匹配时,会导致索引失效

5.2 验证过程

-- 创建phone和department_id列的索引CREATEINDEX idx_phone ON employees(phone);CREATEINDEX idx_dept ON employees(department_id);-- 4.1 字符串列使用数字查询(索引失效)-- phone是VARCHAR类型,使用数字查询会导致隐式转换EXPLAINSELECT*FROM employees WHERE phone =13800138001;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 4.2 优化:使用字符串查询(索引生效)EXPLAINSELECT*FROM employees WHERE phone ='13800138001';-- 结果:type = ref, key = idx_phone(使用索引查找)-- 4.3 数字列使用字符串查询(索引可能生效)-- department_id是INT类型EXPLAINSELECT*FROM employees WHERE department_id ='1';-- 结果:type = ref, key = idx_dept(MySQL自动转换,索引可能生效)-- 4.4 日期列使用字符串查询(索引生效)EXPLAINSELECT*FROM employees WHERE hire_date ='2020-01-15';-- 结果:type = ref, key = idx_hire_date(使用索引查找)

5.3 结论

  • 字符串列使用数字查询会导致隐式类型转换,索引失效
  • 应确保查询条件的数据类型与字段类型一致

5.4 优化建议

  • 确保查询条件的数据类型与字段类型一致
  • 使用显式类型转换函数
  • 在应用层进行类型转换

优化示例:

-- 方案1:使用正确的类型WHERE phone ='13800138001'-- 方案2:使用显式类型转换WHERE phone = CAST(13800138001ASCHAR)-- 方案3:应用层类型转换-- 在应用层将数字转换为字符串,然后查询WHERE phone ='13800138001'

六、场景5:联合索引非最左匹配导致索引失效

6.1 问题分析

问题: 联合索引的查询条件不符合最左前缀匹配原则

6.2 验证过程

-- 删除可能影响验证的单列索引DROPINDEXIFEXISTS idx_name ON employees;DROPINDEXIFEXISTS idx_age ON employees;DROPINDEXIFEXISTS idx_dept ON employees;-- 创建联合索引:idx_name_age_dept (name, age, department_id)CREATEINDEX idx_name_age_dept ON employees(name, age, department_id);-- 5.1 使用最左列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三';-- 结果:type = ref, key = idx_name_age_dept, key_len = 403-- 使用了联合索引的第一列-- 5.2 使用最左两列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'AND age =25;-- 结果:type = ref, key = idx_name_age_dept, key_len = 408-- 使用了联合索引的前两列-- 5.3 使用全部三列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'AND age =25AND department_id =1;-- 结果:type = ref, key = idx_name_age_dept, key_len = 412-- 使用了联合索引的全部三列-- 5.4 跳过最左列(索引失效)EXPLAINSELECT*FROM employees WHERE age =25;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 5.5 跳过最左列(索引失效)EXPLAINSELECT*FROM employees WHERE department_id =1;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 5.6 跳过最左列,使用后两列(索引失效)EXPLAINSELECT*FROM employees WHERE age =25AND department_id =1;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 5.7 使用最左列和第三列(部分索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'AND department_id =1;-- 结果:type = ref, key = idx_name_age_dept, key_len = 403-- 只使用了第一列name,跳过了age,department_id未使用-- 5.8 范围查询后的列不生效EXPLAINSELECT*FROM employees WHERE name ='张三'AND age >25AND department_id =1;-- 结果:type = range, key = idx_name_age_dept, key_len = 408-- 只使用了前两列,department_id未使用(因为age是范围查询)

6.3 最左前缀原则

  • 联合索引必须从最左边开始匹配
  • 可以跳过中间的列,但不能跳过最左边的列
  • 范围查询(>、<、BETWEEN、LIKE)后的列不生效

6.4 结论

  • 跳过最左列会导致索引失效
  • 范围查询(>、<、BETWEEN等)后的列无法使用索引
  • 必须从最左边开始匹配

6.5 优化建议

  • 创建联合索引时,将选择性高的列放在前面
  • 根据查询模式设计索引
  • 考虑创建多个单列索引

优化示例:

-- 方案1:遵循最左前缀原则WHERE name ='张三'AND age =25-- 方案2:创建单独的索引CREATEINDEX idx_dept ON employees(department_id);WHERE department_id =1-- 方案3:根据查询模式设计索引-- 如果经常按age查询,创建单独的age索引CREATEINDEX idx_age ON employees(age);WHERE age =25

七、场景6:WHERE子句中的OR导致索引失效

7.1 问题分析

问题: 当查询中存在OR连接的条件时,可能影响索引利用

7.2 验证过程

-- 重新创建单列索引(场景5已删除)CREATEINDEX idx_name ON employees(name);CREATEINDEX idx_age ON employees(age);CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_dept ON employees(department_id);-- 6.1 OR连接不同索引列(索引失效)EXPLAINSELECT*FROM employees WHERE name ='张三'OR age =25;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 6.2 OR连接不同索引列(索引失效)EXPLAINSELECT*FROM employees WHERE salary >10000OR department_id =1;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 6.3 OR连接同一索引列(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'OR name ='李四';-- 结果:type = range, key = idx_name(使用索引范围扫描)-- 6.4 优化:使用IN代替OR(索引生效)EXPLAINSELECT*FROM employees WHERE name IN('张三','李四');-- 结果:type = range, key = idx_name(使用索引范围扫描)-- 6.5 优化:使用UNION代替OR(索引生效)EXPLAINSELECT*FROM employees WHERE name ='张三'UNIONSELECT*FROM employees WHERE age =25;-- 结果:两个查询都使用索引-- 第一个查询:type = ref, key = idx_name-- 第二个查询:type = ref, key = idx_age-- 6.6 OR连接有索引列和无索引列(索引失效)-- 删除salary索引DROPINDEX idx_salary ON employees;EXPLAINSELECT*FROM employees WHERE name ='张三'OR salary >10000;-- 结果:type = ALL, key = NULL(全表扫描,索引失效)-- 重新创建索引CREATEINDEX idx_salary ON employees(salary);

7.3 结论

  • OR连接不同索引列会导致索引失效
  • OR连接同一索引列可以使用索引
  • 可以使用IN或UNION代替OR

7.4 优化建议

  • 尽量使用IN代替OR
  • 使用UNION ALL代替OR(如果确定无重复)
  • 确保OR条件使用同一索引

优化示例:

-- 方案1:使用IN代替ORWHERE name IN('张三','李四')-- 方案2:使用UNION代替ORSELECT*FROM employees WHERE name ='张三'UNIONSELECT*FROM employees WHERE age =25-- 方案3:使用UNION ALL(如果确定无重复)SELECT*FROM employees WHERE name ='张三'UNIONALLSELECT*FROM employees WHERE age =25

八、索引失效场景总结表

场景示例SQL索引状态type优化建议
左模糊匹配WHERE name LIKE '%张'失效ALL使用右模糊或全文索引
左右模糊匹配WHERE name LIKE '%张%'失效ALL使用右模糊或全文索引
右模糊匹配WHERE name LIKE '张%'生效range-
函数操作WHERE YEAR(hire_date) = 2020失效ALL使用范围查询
表达式计算WHERE salary + 1000 > 10000失效ALL计算移到右边
隐式类型转换WHERE phone = 13800138001失效ALL使用字符串类型
联合索引跳过最左列WHERE age = 25失效ALL遵循最左前缀原则
OR连接不同索引列WHERE name = '张' OR age = 25失效ALL使用UNION或IN

九、完整验证脚本

-- ========================================-- 完整验证脚本:从头开始验证所有场景-- ========================================-- 1. 删除已存在的表(如果存在)DROPTABLEIFEXISTS employees;-- 2. 创建员工表(不创建索引)CREATETABLE employees ( id INTPRIMARYKEYAUTO_INCREMENT, name VARCHAR(100), age INT, phone VARCHAR(20), salary DECIMAL(10,2), department_id INT, hire_date DATE);-- 3. 插入测试数据INSERTINTO employees (name, age, phone, salary, department_id, hire_date)VALUES('张三',25,'13800138001',8000.00,1,'2020-01-15'),('李四',30,'13800138002',12000.00,2,'2019-06-20'),('王五',28,'13800138003',9500.00,1,'2021-03-10'),('赵六',35,'13800138004',15000.00,3,'2018-11-05'),('钱七',27,'13800138005',10000.00,2,'2020-08-22'),('张伟',32,'13800138006',13000.00,1,'2019-04-18'),('李娜',29,'13800138007',11000.00,3,'2021-01-30'),('王芳',26,'13800138008',8500.00,2,'2020-12-01'),('赵强',31,'13800138009',14000.00,1,'2018-07-15'),('钱龙',33,'13800138010',16000.00,3,'2017-09-20');-- ========================================-- 场景1:模糊匹配-- ========================================SELECT'========== 场景1:模糊匹配 =========='AS test_case;CREATEINDEX idx_name ON employees(name);SELECT'1.1 左模糊匹配(索引失效)';EXPLAINSELECT*FROM employees WHERE name LIKE'%张';SELECT'1.2 左右模糊匹配(索引失效)';EXPLAINSELECT*FROM employees WHERE name LIKE'%张%';SELECT'1.3 右模糊匹配(索引生效)';EXPLAINSELECT*FROM employees WHERE name LIKE'张%';SELECT'1.4 精确匹配(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三';-- ========================================-- 场景2:函数操作-- ========================================SELECT'========== 场景2:函数操作 =========='AS test_case;CREATEINDEX idx_hire_date ON employees(hire_date);SELECT'2.1 使用YEAR函数(索引失效)';EXPLAINSELECT*FROM employees WHEREYEAR(hire_date)=2020;SELECT'2.2 使用MONTH函数(索引失效)';EXPLAINSELECT*FROM employees WHEREMONTH(hire_date)=6;SELECT'2.3 优化:使用范围查询(索引生效)';EXPLAINSELECT*FROM employees WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31';-- ========================================-- 场景3:表达式计算-- ========================================SELECT'========== 场景3:表达式计算 =========='AS test_case;CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_age ON employees(age);SELECT'3.1 索引列参与计算(索引失效)';EXPLAINSELECT*FROM employees WHERE salary +1000>10000;SELECT'3.2 索引列参与计算(索引失效)';EXPLAINSELECT*FROM employees WHERE age -5>20;SELECT'3.3 优化:将计算移到右边(索引生效)';EXPLAINSELECT*FROM employees WHERE salary >9000;-- ========================================-- 场景4:隐式类型转换-- ========================================SELECT'========== 场景4:隐式类型转换 =========='AS test_case;CREATEINDEX idx_phone ON employees(phone);CREATEINDEX idx_dept ON employees(department_id);SELECT'4.1 字符串列使用数字查询(索引失效)';EXPLAINSELECT*FROM employees WHERE phone =13800138001;SELECT'4.2 优化:使用字符串查询(索引生效)';EXPLAINSELECT*FROM employees WHERE phone ='13800138001';-- ========================================-- 场景5:联合索引非最左匹配-- ========================================SELECT'========== 场景5:联合索引非最左匹配 =========='AS test_case;-- 删除可能影响验证的单列索引DROPINDEX idx_name ON employees;DROPINDEX idx_age ON employees;DROPINDEX idx_dept ON employees;-- 创建联合索引CREATEINDEX idx_name_age_dept ON employees(name, age, department_id);SELECT'5.1 使用最左列(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三';SELECT'5.2 使用最左两列(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三'AND age =25;SELECT'5.3 跳过最左列(索引失效)';EXPLAINSELECT*FROM employees WHERE age =25;SELECT'5.4 跳过最左列,使用后两列(索引失效)';EXPLAINSELECT*FROM employees WHERE age =25AND department_id =1;-- ========================================-- 场景6:OR条件-- ========================================SELECT'========== 场景6:OR条件 =========='AS test_case;-- 重新创建单列索引CREATEINDEX idx_name ON employees(name);CREATEINDEX idx_age ON employees(age);CREATEINDEX idx_salary ON employees(salary);CREATEINDEX idx_dept ON employees(department_id);SELECT'6.1 OR连接不同索引列(索引失效)';EXPLAINSELECT*FROM employees WHERE name ='张三'OR age =25;SELECT'6.2 OR连接同一索引列(索引生效)';EXPLAINSELECT*FROM employees WHERE name ='张三'OR name ='李四';SELECT'6.3 优化:使用IN代替OR(索引生效)';EXPLAINSELECT*FROM employees WHERE name IN('张三','李四');-- ========================================-- 验证完成-- ========================================SELECT'========== 验证完成 =========='AS message;SHOWINDEXFROM employees;

十、优化建议总结

10.1 模糊查询优化

-- 避免WHERE name LIKE'%张%'-- 推荐WHERE name LIKE'张%'-- 或使用全文索引WHEREMATCH(name) AGAINST('张')

10.2 函数操作优化

-- 避免WHEREYEAR(hire_date)=2020-- 推荐WHERE hire_date BETWEEN'2020-01-01'AND'2020-12-31'

10.3 表达式计算优化

-- 避免WHERE salary +1000>10000-- 推荐WHERE salary >9000

10.4 类型转换优化

-- 避免(phone是VARCHAR类型)WHERE phone =13800138001-- 推荐WHERE phone ='13800138001'

10.5 联合索引优化

-- 联合索引:(name, age, department_id)-- 避免WHERE age =25-- 推荐WHERE name ='张三'AND age =25

10.6 OR条件优化

-- 避免WHERE name ='张三'OR age =25-- 推荐WHERE name IN('张三','李四')-- 或SELECT*FROM employees WHERE name ='张三'UNIONSELECT*FROM employees WHERE age =25

十一、总结

通过EXPLAIN命令验证,我们确认了以下6种常见的索引失效场景:

  1. 模糊匹配:左模糊和左右模糊导致索引失效
  2. 函数操作:对索引列使用函数破坏索引有序性
  3. 表达式计算:索引列参与计算导致索引失效
  4. 隐式类型转换:数据类型不匹配导致索引失效
  5. 联合索引非最左匹配:跳过最左列导致索引失效
  6. OR条件:OR连接不同索引列导致索引失效

关键指标:

  • type = ALL:全表扫描,索引失效
  • key = NULL:未使用索引
  • type = ref/range:使用索引查找/范围扫描
  • key = idx_xxx:使用了指定索引

验证方法:

  • 采用"按需创建索引"的方式,避免预先创建的索引影响验证结果
  • 每个场景独立验证,确保结果准确
  • 提供完整的验证脚本,可以一键运行

通过合理使用EXPLAIN,你可以对查询进行深入分析,找出性能瓶颈,从而提升数据库性能。

延伸阅读:
如果你想了解EXPLAIN命令的基础知识和12个输出字段的详细解释,请阅读我的另一篇文章《MySQL EXPLAIN命令详解:SQL查询性能分析与优化指南(基础篇)》。


Read more

【数据结构】排序详解:从快速排序分区逻辑,到携手冒泡排序的算法效率深度评测

【数据结构】排序详解:从快速排序分区逻辑,到携手冒泡排序的算法效率深度评测

🔥@晨非辰Tong: 个人主页 👀专栏:《C语言》、《数据结构与算法入门指南》 💪学习阶段:C语言、数据结构与算法初学者 ⏳“人理解迭代,神理解递归。” 文章目录 * 引言 * 一、介绍交换排序 * 二、高效交换--快速排序“:递归版 * 2.1 介绍:创造背景以及基本思想 * 2.2 基于二叉树结构的主体框架 * 三、找基准值key的三种==递归版==实战方法 * 3.1 快排核心构成:寻找key的算法之"hoare"版本 * 3.3.1 画图理解算法 * 3.3.2 代码实战 * 3.1.3 ==**代码分析**== * 3.2

By Ne0inhk
【C++ 算法】DFS & BFS 一篇速成学习

【C++ 算法】DFS & BFS 一篇速成学习

📃个人主页:island1314 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 * 生活总是不会一帆风顺,前进的道路也不会永远一马平川,如何面对挫折影响人生走向 – 《人民日报》 🔥 目录 * 一、DFS * 1. 基本思想 * 2. 特点 * 3. C++实现 * 4. 经典例题 * 例题1:八皇后(洛谷P1219) * 例题2:奇怪的电梯(洛谷P1135) * 例题3:选数(洛谷P1036) * 例题4:迷宫(洛谷P1605) * 例题5:吃奶酪(洛谷P1433) * 例题6:单词搜索(LeetCode 79) * 二、BFS * 1. 基本思想 * 2. 特点 * 3. C++实现

By Ne0inhk
【C语言】数据结构——顺序表超详解!!!(包含顺序表的实现)

【C语言】数据结构——顺序表超详解!!!(包含顺序表的实现)

【C语言】数据结构——顺序表超详解!!!--包含顺序表的实现-- * 一、什么是数据结构 * 二、顺序表 * 1.线性表 * 2.顺序表定义 * 3.顺序表的分类 * (1) 静态顺序表 * (2) 动态顺序表 * 三、动态顺序表的实现(重点!!!) * 1.创建头文件&源文件 * 2.定义动态顺序表(定义) * 3.顺序表的初始化(初始化) * 4.顺序表的销毁(销毁) * 5.顺序表的打印(打印) * 6.顺序表开辟空间(增容) * 7.在顺序表尾部插入数据(尾插) * 8.在顺序表头部插入数据(头插) * 9.在顺序表尾部删除数据(尾删) * 10.

By Ne0inhk
【C语言】排序算法——希尔排序以及插入排序 ——详解!!!

【C语言】排序算法——希尔排序以及插入排序 ——详解!!!

【C语言】排序算法——希尔排序以及插入排序详解 * 前言 * 一 、插入排序 * 1. 视频演示 * 2. 算法思想 * 3. 实现思路 * 4. 代码演示 * 二 、希尔排序 * 1. 视频演示 * 2. 算法思想 * 3. 实现思路 * (1)分组 * (2)预排序 * (3)最终排序 * (4)gap的取值 * 4. 代码演示 * 结语 前言 在学习循环的时候,我们学习到了冒泡排序这个算法 那么,除了冒泡排序,还有什么排序算法呢? 今天给大家带来的是插入排序以及希尔排序 一 、插入排序 1. 视频演示 首先给大家看一段视频,让大家先看看插入排序是怎么运行的 插入排序演示 2. 算法思想 我们可以从视频里看见,

By Ne0inhk