1. 冒泡排序算法介绍
冒泡排序是最简单的排序算法,如果相邻元素的顺序错误,则通过反复交换相邻元素来工作。Java 中的冒泡排序不是对数组进行排序的最佳方法,但却是最基本的实现之一。在本文中,我们将学习如何用 Java 编写冒泡排序程序。
2. 冒泡排序算法原理
冒泡排序算法是重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。重复进行直到没有再需要交换的元素,这意味着数列已经排序完成。
冒泡排序算法适用于小型数据集,对大型数据集排序性能较差,不建议使用!
以下是 Java 中使用冒泡排序按升序对数组进行排序的算法:
void bubbleSort(int arr[])
{
int n = arr.length;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1]) {
// 交换 temp and arr[i]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
- 从数组的第一个元素开始,依次比较相邻的两个元素。
- 如果前一个元素大于后一个元素,交换它们的位置。
- 继续比较下一对相邻元素,直到最后一个元素。
- 重复以上步骤,每一轮比较都会将最大的元素"冒泡"到最后面。
- 当比较结束时,此时数组已经排好序,排序结束。
3. 冒泡排序示例
3.1 第一步
比较相邻的元素。如果第一个比第二个大(即,按照升序排序),就交换它们两个。
给定数组: [ 8,7,5,2] ,从 pos=1 遍历到 pos=4 ,如果该数字小于前一个元素,则将该数字与前一个元素交换。
3.2 第二步
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该是最大的数。
对 pos=1 至 pos=3 重复上一步
3.3 第三步
针对所有的元素重复以上的步骤,除了最后一个。
按照步骤 1 将 pos=1 改为 pos=2
3.4 第四步
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数需要比较。
因为现在 pos=1 到 pos=1 意味着数组现在已完全排序
4. Java 中的冒泡排序程序
下面是用 Java 实现冒泡排序的程序
// Java program for implementation
// of Bubble Sort
class BubbleSort {
void bubbleSort(int arr[])
{
int n = arr.length;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1]) {
// swap temp and arr[i]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
// Prints the array
void printArray(int arr[])
{
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
// Driver method to test above
public static void main(String args[])
{
BubbleSort ob = new BubbleSort();
int arr[] = { 64, 34, 25, 12, 22, 11, 90 };
ob.bubbleSort(arr);
System.out.println("Sorted array");
ob.printArray(arr);
}
}
排序数组
11 12 22 25 34 64 90
4.1 冒泡排序的复杂性和稳定性分析
时间复杂度分析:在最坏的情况下,冒泡排序需要进行n-1轮比较,每轮比较需要进行n-i次。因此,总的比较次数为(n-1) + (n-2) + … + 2 + 1 = n(n-1)/2,近似为O(n2)。
空间复杂度分析:使用了常数个变量,因此空间复杂度为O(1)。
4.2 稳定性分析
什么是稳定性?
答:稳定性指的是相同的数据所在的位置经过排序后是否发生变化。换句话说就是大小相同的两个值在排序之前和排序之后的先后顺序不变,这就是稳定的。
稳定性分析:冒泡排序将小的元素往前调或者把大的元素往后调;比较的是相邻的两个元素,交换也发生在这两个元素之间;因为相等的元素不会进行交换,所以稳定。
4.3 冒泡排序的优点
尽管冒泡排序有点慢,但它也具有某些优点,如下所示:
- 易于实施和理解。
- 由于不需要额外的内存,该算法的空间复杂度为 O(1)。
- 它是一种稳定的排序算法,这意味着具有相同键值的元素在排序输出中保持其相对顺序。
5. 冒泡排序算法性能优化
既然冒泡排序算法存在巨大的性能开销,那么如何优化它呢?
在Java中,冒泡排序算法的优化主要是减少不必要的比较和交换。以下是优化的步骤:
-
引入一个标记,如果在一次遍历中没有发生交换,则说明数组已经排序好了,可以直接退出循环。
-
使用局部变量缓存被比较的元素,减少重复的访问数组的次数。
优化后的代码示例
public class BubbleSortOptimized {
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
boolean swapped;
int temp;
int length = arr.length;
do {
swapped = false;
for (int i = 1; i < length; i++) {
if (arr[i - 1] > arr[i]) {
temp = arr[i - 1];
arr[i - 1] = arr[i];
arr[i] = temp;
swapped = true;
}
}
length--; // 每次循环后,最后一个元素必然是已排序的,下次循环不需要再比较它
} while (swapped);
}
public static void main(String[] args) {
int[] arr = { 4, 3, 2, 1, 5 };
bubbleSort(arr);
// 输出排序后的数组
for (int i : arr) {
System.out.print(i + " ");
}
}
}
在这段代码中,我们使用了swapped
标记来优化算法。如果在一次遍历过程中没有发生任何交换,那么数组就已经是排序好的,因此可以提前退出循环。同时,使用局部变量temp
来缓存被比较的元素,减少了数组访问的次数,从而提高了性能。
6. 总结
综上,冒泡排序是一种简单的排序算法,工作原理是通过重复遍历待排序的数列,比较每对相邻元素的值,若发现顺序错误则交换它们的位置。这个过程会重复进行,直到没有需要交换的元素为止,此时数列就已经排序完成。
冒泡排序算法适用于小型数据集,对大型数据集排序性能较差,不建议使用!