冒泡排序
面试中很多笔试题都有冒泡排序的算法,今天我就整理一下。
1、定义
百度百科:
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
2、原理
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
3、时间复杂度:O(N^2)
4、代码示例
1、根据原理简单实现
public int[] bubbleSort1(int[] initArr){
if(initArr.length > 1){
for(int i =0; i < initArr.length; i++){
for(int j =0; j < initArr.length-i-1; j++){
if(initArr[j] > initArr[j+1]){
int temp = initArr[j];
initArr[j] = initArr[j+1];
initArr[j+1] = temp;
}
}
}
}
return initArr;
}
以上采用双循环方式,外层表示循环次数,内层表示实际操作的相关处理。
2、简单优化策略
采用以上循环策略,方法会机械的执行,即使在某一次执行后他已经完成排序了,如下图所示,第六次排序已经获取到了最终结果,可是他还要重复执行第七、八轮排序。
图片来自网络,侵删/** *简单优化:如果在某一轮已经能获取正确结果,无需之后的排序 * 原理:在方法一的基础上,通过添加标记符isSort,如果有位置交换就说明是无序的,否则是有序的 * @param initArr */ public int[] bubbleSort2(int[] initArr){ if(initArr.length > 1){ for(int i =0; i < initArr.length; i++){ boolean isSorted = true; for(int j =0; j < initArr.length-i-1; j++){ if(initArr[j] > initArr[j+1]){ int temp = initArr[j]; initArr[j] = initArr[j+1]; initArr[j+1] = temp; isSorted = false; } } if(isSorted){ break; } } } return initArr; }
4、进阶优化
如图一个新的待排序数组,我们可以发现后面四个无需排序,只有前面四个才需要排序。
图片来源于网络,侵删。
如果以上我们可以定义一个排序边界(sortBorder)用来区分:有序去和无序区。
如何定义这个边界?我们可以记录每次交换的最后一个元素位置,那么这个位置就可以认为是边界位置。
/** * 进阶优化:定义有序区和无序区,只排序无序区的元素 * 原理:通过记录最后一次交换元素的位置,把这个位置默认成无序区和有序区的边界 * @param initArr */ public int[] bubbleSort3(int[] initArr){ if(initArr.length > 1){ //记录最后一次交换的位置 int lastExchangeIndex = 0; //内层循环的边界位置 int sortBorder = initArr.length-1; for(int i =0; i < initArr.length; i++){ boolean isSorted = true; for(int j =0; j < sortBorder; j++){ if(initArr[j] > initArr[j+1]){ int temp = initArr[j]; initArr[j] = initArr[j+1]; initArr[j+1] = temp; isSorted = false; lastExchangeIndex = j; } } sortBorder = lastExchangeIndex; if(isSorted){ break; } } } return initArr; }
冒泡排序是单向冒泡的,双向冒泡的也有,叫做鸡尾酒冒泡。有时间再介绍。

浙公网安备 33010602011771号