冒泡排序(Java)
声明:本文参考https://www.cnblogs.com/kalton/p/13649798.html
一、原理
- 比较两个相邻的元素,将值大的元素交换到右边
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
二、优化原理
如果在某次单趟排序中没有发生元素的交换,可以说明整个待排序列已经有序
三、时间复杂度
时间复杂度为O(n^2)
四、代码实现(基本代码)
1 //冒泡排序 2 public class bubbleSort { 3 public static int[] sort(int arr[]) { 4 System.out.println("------冒泡排序------"); 5 int tmp = 0; 6 for (int i = 0; i < arr.length-1; i++) { 7 for (int j = arr.length-1; j > i; j--) { 8 if (arr[j] < arr[j-1]) { 9 //进行交换 10 tmp = arr[j]; 11 arr[j] = arr[j-1]; 12 arr[j-1] = tmp; 13 } 14 } 15 } 16 return arr; 17 } 18 }
五、优化代码(一)
public static void bubbleSort(int[] arr){ if (arr == null || arr.length == 0) return;//无序数列的边界,每次比较只需要比到这里为止 int sortBorder = arr.length-1; for (int i = 0; i < arr.length - 1; i++) { //是否已经有序的标记,默认有序 boolean isSorted = true; for (int j = 0; j < sortBorder; j++) { int tmp = 0; //升序排序>,降序排序< if (arr[j] > arr[j + 1]){ tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; //发生元素交换,序列仍是无序状态 isSorted = false; } }
//如果没有发生交换,则待排序列已有序,退出一重循环 if (isSorted){ break; } } }
六、优化代码(二):鸡尾酒排序
优点:能够在特定条件下,减少排序的回合数
缺点:代码量几乎增加了1倍
应用场景:无序数列中大部分元素已经有序
public static void cockTailSort(int[] arr){ if (arr == null || arr.length == 0) return; // 记录右侧最后一次交换的位置 int lastRightExchangeIndex = 0; // 记录左侧最后一次交换的位置 int lastLeftExchangeIndex = 0; // 无序数列的右边界,每次比较只需要比到这里为止 int rightSortBorder = arr.length - 1; // 无序数列的左边界,每次比较只需要比到这里为止 int leftSortBorder = 0; //i设置为1,代表从第1轮开始 for (int i = 1; i < arr.length; i++) { boolean isSorted = true; //奇数,从左到右 if (i % 2 != 0) { for (int j = leftSortBorder; j < rightSortBorder; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; //发生元素交换,序列仍是无序状态 isSorted = false; //更新为右侧最后一次交换元素的位置 lastRightExchangeIndex = j; } } } else { //偶数,从右到左 for (int j = rightSortBorder; j > leftSortBorder; j--) { if (arr[j] < arr[j - 1]) { int temp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = temp; //发生元素交换,序列仍是无序状态 isSorted = false; //更新为左侧最后一次交换元素的位置 lastLeftExchangeIndex = j; } } } //更新无序数列的左边界 leftSortBorder = lastLeftExchangeIndex; //更新无序数列的右边界 rightSortBorder = lastRightExchangeIndex; if (isSorted) { break; } } }