Java冒泡排序
需求:假设有一组数据:10,11,36,51,98,38,57我们要将其排序。
此篇文章介绍众多排序算法中其中简单经典的一个:冒泡排序。
冒泡排序
冒泡排序的算法思想为:(以下来自百度百科)
重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
我们用上述的例子来解释:
排序过程
原始数据:10,11,36,51,98,38,57
首先,我们从第一个元素开始,将该组数据按升序排序。
第一轮:
10和11比较,11比10大,继续,36与11比较,36比11大,继续,51和36比较,51大,继续,98和51比较,98大,继续,38和98比较,98大,交换它们两个的位置,现在变成了10,11,36,51,38,98,57,所以接下来是57和98比较,98大,交换,所以现在为10,11,36,51,38,57,98;
现在可以看到经过6次比较,98已经在最后了,所以这一轮确定了最大的那个数。
10,11,36,51,38,57,98
第二轮:
10和11比较,11比10大,继续,36与11比较,36比11大,继续,51和36比较,51大,继续,51和38比较,51大,交换它们两个的位置,现在变成了10,11,36,38,51,57,98,所以接下来是57和51比较,57大,因为最后一个数字在最后一轮的时候已经确定为了第一大的数字,所以无需再进行比较;
经过5次比较,这一轮确定了第二大的那个数。
10,11,36,38,51,57,98
第三轮:
虽然现在我们可以看出数据已经按升序排好了,但是程序是没有办法判断的,所以我们还是要一次一次的进行比较,直到比较完全部的数据,才能确定此时为我们所需要的升序排序。
10和11比较,11比10大,继续,36与11比较,36比11大,继续,38和36比较,38比36大,继续,51和38比较,51比38大,继续,因为前两次已经确定了后两位数,所以此次无需进行比较了;
经过4次比较,这一轮确定了第三大的那个数。
10,11,36,38,51,57,98
第四轮:
10和11比较,11比10大,继续,36与11比较,36比11大,继续,38和36比较,38比36大,无需比较最后三位数;
经过3次比较,这一轮确定了第四大的那个数。
10,11,36,38,51,57,98
第五轮:
10和11比较,11比10大,继续,36与11比较,36比11大,无需比较后面四位数;
经过2次比较,这一轮确定了第五大的那个数。
10,11,36,38,51,57,98
第六轮:
10和11比较,无需比较后面五位数;
经过2次比较,这一轮确定了第六大的那个数。
10,11,36,38,51,57,98
10没有数据再与它比较了,所以最后的顺序即为:10,11,36,38,51,57,98
上述排序,不仅仅可以将最大的浮到最后,还可以将小的浮到最前面,看个人喜欢。
排序总结:
假设数组数据总个数为n:
循环轮次:n-1;
每轮次比较为:n-轮次(从1开始)
实现代码
在整个的实现代码之前,我们需要先知道两个数据怎么进行交换:
就像两只装满水的桶,怎么互相把水倒进对方桶里,肯定不能直接倒,需要借助一下第3个桶才行;
先把第1个桶里的水倒进第3个,现在就可以把第2个桶的水倒进第1个,再把第3个桶里的水倒进第2个,这样就能实现交换需求。
Java中两个变量交换也是一样的道理。
a,b两个变量,再定义一个temp
a->temp;
b->a;
temp->b。
//冒泡排序
package com.dh.array;
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {10,11,36,51,98,38,57};
int temp = 0;
for(int i = 1;i<=arr.length-1;i++){ //轮次
for(int j = 0;j<arr.length-i;j++){ //每轮比较次数
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
for (int arrTemp : arr) { //输出每轮排序之后的结果
System.out.print(arrTemp+"\t");
}
System.out.println();
}
}
}
冒泡排序优化
在第三轮比较的时候就已经没有发生交换,排好序了,却还要继续程序的运行,这肯定是存在问题的;
所以我们可以判断是否进行交换操作,如果这轮交换了数据,就继续,如果没有进行数据交换,就说明这已经是排好序了的,就退出排序,直接得到最后的结果。
package com.dh.array;
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {10,11,36,51,98,38,57};
int temp = 0;
boolean flag = false; //用于判断是否交换的变量
for(int i = 1;i<=arr.length-1;i++){ //轮次
for(int j = 0;j<arr.length-i;j++){ //每轮比较次数
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true; //如果交换了就置为true,没有交换则为false
}
}
for (int arrTemp : arr) { //输出每轮排序之后的结果
System.out.print(arrTemp+"\t");
}
System.out.println();
if(flag == false){ //为false的话说明没有进行交换,就退出排序
break;
}
flag = false; //记得将flag设回初始值,否则flag变为true之后就一值为true了
}
}
}
冒泡排序可以向前冒也可以向后冒,可以将大的数冒也可以将小的数冒,怎么使用取决于自己喜欢~(任性!)
水平有限,有错误请指出~
愿以渺小启程,以伟大结束。