一、冒泡排序原理:
这里我们的排序是默认排成从小到大的顺序的:
思路:
依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
第一趟比较完成后,最后一个数一定是数组中最大的一个数,所以第二趟比较的时候最后一个数不参与比较;
第二趟比较完成后,倒数第二个数也一定是数组中第二大的数,所以第三趟比较的时候最后两个数不参与比较;
依次类推,每一趟比较次数-1;
代码:
for(int i=0;i<arr.length-1;i++){//外层循环控制排序趟数
for(int j=0;j<arr.length-1-i;j++){//内层循环控制每一趟排序多少次
//arr.length-1-i的原因是:每跑一趟就会让一个数字变得有序,下次时可以忽略这个数字
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
//保证大的数字在后
}
}
}
冒泡排序的平均时间复杂度是O(n2)、空间复杂度是O(1)、是一个稳定的排序算法。
二、冒泡排序算法的优化:
实际排序中,我们可能遇到的要排序的数字并不是全部都混杂无章的,有时候我们会遇到不需要我们排序的情况(例如1 2 3 4 5排序),这种时候如果用原先的排序算法的话会导致过于繁杂。因此我们需要让算法之中加入可以自行判断是否需要排序的部分。
代码:
boolean needNextSort = true;//控制排序的布尔变量
for(int i=0; i<array.length-1 && needNextSort; i++){//外层循环控制排序趟数
needNextSort = false;
for(int j=0; j<array.length-i-1; j++){//内层循环控制每一趟排序多少次
if(array[j] > array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
needNextSort = true;
}
}
}
在代码中我们加入了一个布尔类型变量用于判断是否需要排序。当该布尔类型变量为true时,证明我们还需要进行排序。我们在外层控制循环的部分将变量设置为false,然后如果内层判断到有需要进行排序的部分时就会执行排序同时让布尔变量变为true,以便于下一次能够进入循环检查是否排序成功。
如果检查的过程中发现依然还有需要排序的部分时会再次进行排序并将布尔变量置为true,等待下一次的检查。
如果检查的过程中发现没有任何需要排序的部分,那么在进入外层循环时置为false的布尔变量就还是false,这样在下一次即将进入外层循环的时候就会由于布尔变量是false从而跳出循环。