基本介绍
冒泡排序(Bubble Sorting)的基本思想是通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args){
int arr[] = {3,5,-9,10,-10};
int temp = 0;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组");
System.out.println(Arrays.toString(arr));
}
}
}
优化
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args){
int arr[] = {3,5,-9,10,-10};
//int arr[] = {2,1,5,6,8,9};
int temp = 0;
boolean flag = true; //标记变量
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = false;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组");
System.out.println(Arrays.toString(arr));
if(flag){ // 在一趟排序中,一次交换都没有发生过
break;
}else{
flag = true;//重置flag,进行下次判断
}
}
}
}
小结
1.一共进行数组的大小减1次的循环
2.每一趟排序的次数在逐渐的减少
3.如果发现在某趟排序中,没有再发生交换动作,则可以提前结束冒泡排序(优化项)
4.冒泡排序的时间复杂度n^2
鸡尾酒排序
鸡尾酒排序(Cocktail Sort),也被称为双向冒泡排序、鸡尾酒搅拌排序、涟漪排序、来回排序等,是冒泡排序的一种改进。它的主要改进在于,冒泡排序是单向地从前往后(或从后往前)进行元素的比较和交换,而鸡尾酒排序则是先从前往后进行一遍冒泡排序,然后再从后往前进行一遍冒泡排序,以此类推,直到整个数组排序完成。这种排序方式可以减少排序的轮数,在某些情况下能提高排序的效率。
下面是一个用Java实现的鸡尾酒排序示例:
public class CocktailSort {
public static void cocktailSort(int[] arr) {
if (arr == null || arr.length <= 1) {
return;
}
boolean swapped;
int start = 0;
int end = arr.length - 1;
while (start < end) {
swapped = false;
// 从前向后进行冒泡排序
for (int i = start; i < end; i++) {
if (arr[i] > arr[i + 1]) {
// 交换元素
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
swapped = true;
}
}
// 如果这一轮没有发生交换,说明数组已经有序,可以提前结束
if (!swapped) {
break;
}
// 更新未排序部分的起始位置
swapped = false;
// 从后向前进行冒泡排序
end--;
for (int i = end; i > start; i--) {
if (arr[i] < arr[i - 1]) {
// 交换元素
int temp = arr[i];
arr[i] = arr[i - 1];
arr[i - 1] = temp;
swapped = true;
}
}
// 更新未排序部分的结束位置
start++;
}
}
public static void main(String[] args) {
int[] arr = {5, 3, 8, 4, 2};
cocktailSort(arr);
for (int num : arr) {
System.out.print(num + " ");
}
}
}
在这个示例中,cocktailSort
方法接收一个整数数组 arr
作为参数,并对其进行鸡尾酒排序。它首先定义了两个指针 start
和 end
,分别指向数组的起始位置和结束位置。然后,通过循环,先从前向后进行冒泡排序,如果在这一轮中没有发生任何交换,则说明数组已经有序,可以提前结束排序。否则,更新 end
指针,并从后向前进行冒泡排序,以此类推,直到 start
大于等于 end
,排序完成。
需要注意的是,虽然鸡尾酒排序在某些情况下能提高排序的效率,但其平均和最坏情况下的时间复杂度仍然是 O(n^2),因此它并不适合用于排序大量数据的场景。