白话经典算法系列 - 七大排序总结篇
原文链接:
http://blog.csdn.net/MoreWindows/article/category/859207
1.冒泡排序
核心思路:
双重循环
外层是进行多少轮,一轮冒泡只能排好一个数,所以有n轮;(这是最好的理解方式)
内层是单次冒泡,冒泡的核心是逐个,相邻元素两两比较,如此,一轮冒泡后,最大(最小)元素就跑到最后面了
//核心代码 void sort(int *a, int len) { for (int i = 0; i < len; i++) for (int j = 1; j < len - i; j++) { if (a[j - 1] > a[j]) swap(a[j - 1], a[j]); } }
实现:外层从0到len-1;内层从1到len-i,因为已经排过的就不需要再参与下一次的冒泡了;两两比较,反序则交换。
改进版1:
核心思想:如果某一趟内层没有进行交换,那显然整个数组已经有序,那就可以退出了。
//核心代码 void sort(int *a, int len) { bool flag = true; for (int i = 0; i < len; i++) { for (int j = 1; j < len - i; j++) { if (a[j - 1] > a[j]) { swap(a[j - 1], a[j]); flag = false; } } if (!flag) break; } }
实现:在所有循环外部设置一个标签true,表示此时数组有序;最内层如果交换执行,标签就会被设置为false,表明此时数组无序,仍需进入下一轮;如果内层循环一个也没执行,那标签就是原始的true;在外层循环内设置一个条件跳出器,一旦检测到true就结束外层循环。
改进版,网上有很多有意思的写法,总体就是一个多米诺玩具,相互触发,很好玩。
//巧妙的改写版本 void sort(int *a, int len) { int k = len; bool flag = true; while (flag) { flag = false; for (int j = 1; j < k; j++) { if (a[j - 1] > a[j]) { swap(a[j - 1], a[j]); flag = true; } } k--; } }
改进2:
还有一种情况需要改进,即数组前面部分无序,后面有序(3,2,1,4,5,6,7,8)。此时可以记录那个临界的位置,下次内层冒泡的终点就可以提前。
//这种算法还是少些得好,太晦涩 void sort(int *a, int len) { int flag = len; while (flag > 0) { int k = flag; flag = 0; for (int j = 1; j < k; j++) { if (a[j - 1] > a[j]) { swap(a[j - 1], a[j]); flag = j; } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)