经典算法——冒泡排序(Bubble Sort)
一、示例代码(伸手党看这里)
1.示例一
import java.util.Arrays;
public class BubbleSort {
public static void bubbleSort(int[] arr){
int temp; /* 临时变量,交换数据时使用 */
int length = arr.length;
for(int p = length-1; p > 0; p--){ /* 需要进行N-1(数组长度减一)趟排序 */
for(int i = 0; i < p; i++){ /* 开始排序 */
if(arr[i] > arr[i+1]){
// 进行位置交换
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
}
public static void main(String[] args) {
int[] a = {10, 2, 5, 7, 23, 59, 3};
bubbleSort(a);
System.out.println(Arrays.toString(a));
}
}
当然,上面的代码可以小小的优化一下。
在使用冒泡排序的时候有可能会遇到这样一种情况:某一趟排序从头到尾,数组中的数字都没有发生位置交换。
那么上面这种情况说明了什么呢?说明了在经过上一趟的排序后,整个数组就已经被排好序了。
这么说的话原来计划的N-1趟排序我们是不是可以不用跑满了?是的!
所以可以优化的地方是:在每一趟排序排完后,看一下这一趟有没有发生数字位置的交换(形象点说就是看看这趟有没有白跑233)。我们借助一个变量实现这个功能。
2.示例二(优化后的冒泡排序)
与示例一不同的地方用红色字体标出
import java.util.Arrays;
public class BubbleSort {
public static void bubbleSort(int[] arr){
int temp; /* 临时变量,交换数据时使用 */
int length = arr.length;
for(int p = length-1; p > 0; p--){ /* 需要进行N-1(数组长度减一)趟排序 */
int flag = 0; /* 一个标识变量,如果某一趟排序时数组中的数字发生了位置交换,其值变为1 */
for(int i = 0; i < p; i++){ /* 开始排序 */
if(arr[i] > arr[i+1]){
// 进行位置交换
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
flag = 1;
}
}
if(flag == 0){
break; /* 全程无交换 */
}
}
}
public static void main(String[] args) {
int[] a = {10, 2, 5, 7, 23, 59, 3};
bubbleSort(a);
System.out.println(Arrays.toString(a));
}
}
二、冒泡排序原理
1.原理
依次比较数组中两个相邻的数,将值大的放在右边。这样看起来数组中的数字就像水底的泡泡,越往上浮,越接近水面(数组的最右边)变得越大。
2.实现思路
假设数组中有5个数。我们依次比较相邻的两个数,将小数放在前面,大数放在后面。
第一趟排序:
先比较第一个数和第二个数,把小的放左边,大的放右边;
再比较第二个数和第三个数,把小的放左边,大的放右边;
然后比较第三个数和第四个数,把小的放左边,大的放右边;
最后比较第四个数和第五个数,把小的放左边,大的放右边;
上述操作做完了之后,第一趟排序也就排完了。来看看有什么特征,你会发现这时候数组的最右边的一个数(也就是数组中最后一个数)是数组中最大的数。
好了,完成了第一趟排序我们选出了大哥(数组中最大的数字),并且大哥坐上了第一把交椅(数组最右边)。
既然大哥位子坐稳了,就不用参与接下来的斗争了,安心的看着剩下的小弟们选出二哥就行了。
开始第二趟排序:
先比较第一个数和第二个数,把小的放左边,大的放右边;
再比较第二个数和第三个数,把小的放左边,大的放右边;
最后比较第三个数和第四个数,把小的放左边,大的放右边;
第二趟排序完成后,我们选出了二哥,并且二哥坐上了第二把交椅(数组的倒数第二个位置)
开始第三趟排序:
先比较第一个数和第二个数,把小的放左边,大的放右边;
再比较第二个数和第三个数,把小的放左边,大的放右边;
第三趟排序完成后,我们选出了三哥,并且三哥坐上了第三把交椅(数组的倒数第三个位置)
开始第四趟排序:
比较第一个数和第二个数,把小的放左边,大的放右边;
第四趟排序排完后就变成了这样:老四坐第四把交椅(数组的第四个位置),弟中弟老五在瑟瑟发抖(数组的第一个位置)。
当数组完全逆序的时候以上四趟排序会全部发生。也就是常说的N个数要排N-1趟序。
三、时间复杂度
1.最好的情况
当数组是一个从小到大完全有序的数组时:需要将数组遍历一遍所以此时的时间复杂度是O(n)
2.最坏的情况
当数组完全逆序的时候:需要跑完N-1趟,每一趟需要比较N-1次,此时的时间复杂度是O(n²)
3.平均复杂度
结合上述1和2两种情况,冒泡排序的平均时间复杂度是O(n²)
纯手工原创,觉得写得不错点个赞支持下吧 :)