冒泡排序
?>冒泡排序(Bubble Sort)
也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
1、原理
每一趟只能确定将一个数归位。即第一趟只能确定将末位上的数归位,第二趟只能将倒数第 2 位上的数归位,依次类推下去。 如果有 n 个数进行排序,只需将 n-1 个数归位,也就是要进行 n-1 趟操作。 而 “每一趟 ” 都需要从第一位开始进行相邻的两个数的比较,将较大的数放后面, 比较完毕之后向后挪一位继续比较下面两个相邻的两个数大小关系,重复此步骤,直到最后一个还没归位的数。 |
2、动图演示
!>什么时候最快:
当输入的数据已经是正序时(都已经是正序了,我还要你冒泡排序有何用啊)。
!>什么时候最慢:
当输入的数据是反序时(写一个 for 循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗)。
3、代码实现
3.1 JavaScript 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 | function bubbleSort(arr) { var len = arr.length; for ( var i = 0; i < len - 1; i++) { for ( var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]) { // 相邻元素两两对比 var temp = arr[j+1]; // 元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; } |
3.2 Python 代码实现
1 2 3 4 5 6 | def bubbleSort(arr): for i in range ( 1 , len (arr)): for j in range ( 0 , len (arr) - i): if arr[j] > arr[j + 1 ]: arr[j], arr[j + 1 ] = arr[j + 1 ], arr[j] return arr |
3.3 Go 代码实现
1 2 3 4 5 6 7 8 9 10 11 | func bubbleSort(arr []int) []int { length := len(arr) for i := 0; i < length; i++ { for j := 0; j < length-1-i; j++ { if arr[j] > arr[j+1] { arr[j], arr[j+1] = arr[j+1], arr[j] } } } return arr } |
3.4 Java 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static void BubbleSort( int [] arr){ int temp; //临时变量 for ( int i= 0 ; i<arr.length- 1 ; i++){ //表示趟数,一共arr.length-1次。 for ( int j=arr.length- 1 ; j>i; j--){ if (arr[j] < arr[j- 1 ]){ temp = arr[j]; arr[j] = arr[j- 1 ]; arr[j- 1 ] = temp; } } } } |
4、优化(Java)
针对问题(1):
( 发现整个数列已经是有序的了
)– 数据的顺序排好之后,冒泡算法仍然会继续进行下一轮的比较,直到arr.length-1次,后面的比较没有意义的。
方案:
-
设置标志位flag,如果发生了交换flag设置为true;如果没有交换就设置为false。
-
这样当一轮比较结束后如果flag仍为false,即:这一轮没有发生交换,说明数据的顺序已经排好,没有必要继续进行下去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public static void BubbleSort1( int [] arr){ if (arr == null || arr.length < 2 ) { return arr; } int temp; //临时变量 boolean flag; //是否交换的标志 for ( int i= 0 ; i<arr.length- 1 ; i++){ //表示趟数,一共arr.length-1次。 flag = true ; for ( int j=arr.length- 1 ; j>i; j--){ if (arr[j] < arr[j- 1 ]){ temp = arr[j]; arr[j] = arr[j- 1 ]; arr[j- 1 ] = temp; flag = false ; //有元素交换,所以不是有序,标记变为false } } //一趟下来是否发生位置交换,如果没有交换直接跳出大循环 if (flag) break ; } } |
针对问题(2):
( 发现整个数列有序区的界定
)– 数据的顺序排好之后, 在一轮排序后,发现后面其实又是有序数列了,但是还是要每一次两两相比,这样也白白比较了很多次了 。
图例:
方案:
-
记录最后一次交换的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public static int [] BubbleSort( int [] arr) { if (arr == null || arr.length < 2 ) { return arr; } //记录最后一次交换的位置 int lastExchangeIndex = 0 ; //无序数列的边界,每次比较只需要比到这里为止 int sortBorder = arr.length - 1 ; for ( int i = 0 ; i < arr.length - 1 ; i++) { boolean isSorted = true ; //有序标记,每一轮的初始是true for ( int j = 0 ; j < sortBorder; j++) { if (arr[j + 1 ] < arr[j]) { isSorted = false ; //有元素交换,所以不是有序,标记变为false int t = arr[j]; arr[j] = arr[j+ 1 ]; arr[j+ 1 ] = t; lastExchangeIndex = j; } } sortBorder = lastExchangeIndex //一趟下来是否发生位置交换,如果没有交换直接跳出大循环 if (isSorted ) break ; } return arr; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用