原理
为什么叫冒泡排序?是因为小的浮出水面,大的数据都下降到了水底。
基本的思路是:利用遍历的手段比较两个相邻的元素,将值大的元素交换至右端。
模拟流程
如果有四个数 4 1 5 3,
第一趟,我们比较相邻的两个数 4和1,判断4比1大,交换4和1的位置,这时就变成了1 4 5 3,再比较 4和5,判断大小,不用交换位置,接着再比较5和3,判断大小,需要交换位置,这时候顺序就是1 4 3 5了。
第二趟,我们比较相邻的1和4,判断大小,不用交换位置;接着比较4和3,需要交换位置,顺序变为1 3 4 5。由于第一趟已经把最大的数字沉到了最后,所以 4和5不用进行比较了。
第三趟,我们继续比较1和4,不用交换位置,由于第二趟已经把4沉到最后,所以就不用进行3和4 的比较了。
代码实现
package 排序算法;
/**
* Author:haozhixin
* Func: 冒泡排序算法
* Date: 20190809
*/
public class BubbleSort {
//基本的冒泡排序
public static void basicSort(){
int data[] = {4,1,5,3};
//这个表示要比较几趟,就是轮数。
//许多网上教学,视频教学都多比较了一轮,这个要注意下。
for(int i=0;i<data.length-1;i++){
//j的定义要注意下,j每一趟比较都是从第一个数开始的,
//在哪个数结束呢?就是在数组的最后一个比较完成的数之前。
for(int j=0;j<data.length-1-i;j++){
if(data[j]>data[j+1]){
int temp;//普通的数组交换,需要定义中间值存储,这块如果还有不懂的请自行学习。
temp = data[j+1];
data[j+1]=data[j];
data[j]=temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i]);
}
}
public static void main(String[] args){
basicSort();
}
}
冒泡排序的特点就是:每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值
算法优化
通过上面的流程分析,我们能够清楚的看到冒泡排序的缺点:
有的冒泡经过第一轮的交换已经是有序的了,如:2 1 3 4。数据越多的时候越慢,非常不适合大数据的排序
那么我们如何优化一下呢?
如果用一个flag来判断一下,当前数组是否已经有序,如果有序就退出循环,这样可行不呢?
来看代码:
//外层循环优化
public static void basicUpdateSort(){
int[] arr = {5,4,6,9,4,11,10,12};
int temp;
for (int i = 0; i < arr.length-1; i++) {
boolean flag = true;//哎 ,看到好多博客误人子弟,我都看不下去了,竟然将flag定义放到for外层,也是醉了。
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;//如果发生交换了,置为false,下次循环会继续将flag置为true。
}
System.out.println("执行了"+j+"次");
}
if(flag){
//没有发生交换则退出循环;
break;
}
System.out.println("执行了"+i+"趟");
}
System.out.println(Arrays.toString(arr));
}
这种情况只能对外层循环比较的趟数进行控制,但是第二层循环中对相邻数据的比较并没有优化,因为第二层中可能后边的数据都是有序的了。那么我们应该怎么做呢?
//内层循环优化
public static void basicUpdateSort2(){
int[] arr = {5,4,6,9,4,11,10,12};
int temp;
int tempIndex=0;//标记位置
int sortBorder = arr.length-1;
for (int i = 0; i < arr.length-1; i++) {
boolean flag = true;
//执行的每一趟,内存循环都要将相邻的元素进行比较。但是许多后边的元素可以第一次已经有序了
for (int j = 0; j < sortBorder; j++) {
if(arr[j]>arr[j+1]){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag=false;
tempIndex=j;
}
System.out.println("执行了"+j+"次");
}
sortBorder=tempIndex;
if(flag){
break;
}
System.out.println("执行了"+i+"趟");
}
System.out.println(Arrays.toString(arr));
}
看了两篇博客,好多都是瞎JB说,感觉博客质量实在是太差了。
作者:select you from me
来源:CSDN
转载请联系作者获得授权并注明出处。
来源:https://blog.csdn.net/qq_15612527/article/details/98980087