(PS:学习算法,只看不写=没学,如果你能看完这篇文章,请尝试默写即便冒泡排序,如果觉得有用就点个赞,谢谢你的观看)
一、冒泡排序的基本知识
冒泡排序是一种基础的排序算法,它通过重复地遍历待排序数组,比较相邻的元素,并根据排序规则交换它们的位置,从而达到将数组按照升序或降序排列的目的。
下面是冒泡排序的基本步骤:
-
比较相邻元素:从数组的第一个元素开始,依次比较相邻的两个元素。
-
交换位置:如果相邻元素的顺序不符合排序规则(例如,如果是升序排序且前一个元素大于后一个元素),则交换它们的位置。
-
重复遍历:重复执行步骤1和步骤2,直到没有需要交换的元素,即整个数组已经有序。
冒泡排序的时间复杂度为O(n^2),其中n是数组中元素的个数。它的优点是实现简单,逻辑清晰,适用于小型数据集或者已经近乎有序的数据集。然而,由于其时间复杂度较高,在大型数据集上性能较差,因此通常不适用于大规模数据的排序任务。
二、文字解析冒泡排序规则
初始数组:[5, 2, 9, 1, 7]
第一轮冒泡:4次,比较数组长度 - 1 次(往后每轮都在此基础上-1次直到1为止)
比较 5 和 2:5比2大,5与2交换位置 [2, 5, 9, 1, 7]
比较 5 和 9:5比9小,不动 [2, 5, 9, 1, 7]
比较 9 和 1: 9比1大,9与1交换位置 [2, 5, 1, 9, 7]
比较 9 和 7: 9比7大,9与7交换位置 [2, 5, 1, 7, 9]
这样最后一轮比较完毕后,9的位置是确定的,9不用在参与比较,接下来进行第二轮冒泡排序
第二轮冒泡:3次
比较 2 和 5:[2, 5, 1, 7, 9]
比较 5 和 1:[2, 1, 5, 7, 9]
比较 5 和 7:[2, 1, 5, 7, 9]
第二轮冒泡完毕后,7的位置也确定了
第三轮冒泡:2次
比较 2 和 1:[1, 2, 5, 7, 9]
比较 2 和 5:[1, 2, 5, 7, 9]
第四轮冒泡:1次
比较 1 和 2:[1, 2, 5, 7, 9]
这样一个数组的冒泡排序就完毕了,从中我们可以发现,每一轮的冒泡排序后都会得到一个确定位置的数。
三、冒泡排序算法
public class 冒泡排序 {
public static void main(String[] args) {
int[] array = {64, 34, 25, 12, 22, 11, 90};
System.out.println("排序前的数组:");
printArray(array);
bubbleSort(array);
System.out.println("排序后的数组:");
printArray(array);
}
// 冒泡排序函数
static void bubbleSort(int[] array) {
for (int i = 0; i < array.length-1; i++) {
for (int j = 0; j < array.length-i-1; j++) {
// 如果当前元素比下一个元素大,则交换它们的位置
if (array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
// 打印数组元素的函数
static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
}
这个算法的核心就是:
// 冒泡排序函数
static void bubbleSort(int[] array) {
// 外循环 控制需要进行几次冒泡
for (int i = 0; i < array.length-1; i++) {
//内循环 控制需要比较几次
//-i:是因为每进行一次冒泡后,都会有一个确定的数所以不需要在比较了
for (int j = 0; j < array.length-i-1; j++) {
// 如果当前元素比下一个元素大,则交换它们的位置
if (array[j] > array[j+1]) {
int temp = array[j]; //交换位置代码
array[j] = array[j+1];//交换位置代码
array[j+1] = temp;//交换位置代码
}
}
}
}
四、优化冒泡排序
假如说,我们需要排序的数组已经是一个高度有序的数组,例如:[1,2,8,7,9],那理论上来讲,只需要执行一次冒泡排序就可以完成了,但是按照上述的代码,我们仍然需要进行4轮冒泡才结束,这显然是不合理的,所以优化的思路就是:如果在本次遍历中没有发生交换,说明数组已经有序,提前结束排序
来看代码:
public class 冒泡排序改进版 {
public static void main(String[] args) {
int[] array = {64, 34, 25, 12, 22, 11, 90};
System.out.println("排序前的数组:");
printArray(array);
optimizedBubbleSort(array);
System.out.println("排序后的数组:");
printArray(array);
}
static void optimizedBubbleSort(int[] array) {
boolean swapped;
for (int i = 0; i < array.length-1; i++) {
swapped = false;
for (int j = 0; j < array.length-i-1; j++) {
// 如果当前元素比下一个元素大,则交换它们的位置
if (array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
swapped = true;
}
}
// 如果在本次遍历中没有发生交换,说明数组已经有序,提前结束排序
if (!swapped) {
break;
}
}
}
// 打印数组元素的函数
static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
}
我们新增了一个boolean值 swapped,如果发送交换,则把true赋值给它,如果没发送交换,则在低端进行跳出结束冒泡排序函数。
到这里冒泡排序的知识点都完事了,希望你能自己动手做一下,觉得有用就点个赞和收藏。