冒泡排序
原文链接: 冒泡排序
冒泡排序
冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,知道没有反序的记录为止。冒泡的实现上有很多种变化,我们主要介绍3中。
1、最简单的冒泡排序
/**
* Created by liuqiang on 16/4/8.
* 冒泡排序
*/
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {9, 1, 5, 8, 3, 7, 4, 6, 2};
print(arr);
sort(arr);
print(arr);
}
/**
* @param args 待排序的数组
* 思路:让每一个关键字都和他后面的每一个关键字比较,
* 如果大则交换,这样第一个位置的关键字就在一次循环
* 之后变成了最小值
*/
public static void sort(int[] args) {
for (int i = 0; i < args.length; i++) {
for (int j = i + 1; j < args.length; j++) {
if (args[i] > args[j]) {
swap(args, i, j); //交换数组中的两个元素的位置
}
}
}
}
/**
* 交换数组args 中的下标为 i 和 j 的元素
*
* @param args
* @param i
* @param j
*/
public static void swap(int[] args, int i, int j) {
int temp = args[i];
args[i] = args[j];
args[j] = temp;
}
/**
* 数组打印辅助方法
*
* @param args
*/
public static void print(int[] args) {
System.out.print("数组的值: [");
for (int m : args) {
System.out.print(m + ",");
}
System.out.println("]");
}
}
其实以上代码严格意义上来说不算是冒泡排序算法,因为他不满足“两两比较相邻记录”的冒泡思想。它应该算是最简单的交换排序而已。
2、真正的冒泡
/**
* 真正的冒泡排序算法
*
* @param args 待排序的数组
*
*/
public static void sort2(int[] args) {
for (int i = 0; i < args.length; i++) {
for (int j = args.length - 2; j >= i; j--) { //从后往前循环
if (args[j] > args[j + 1]) {
swap(args, j, j + 1);
}
}
}
}
或者
public static void sort3(int[] args) {
for (int i = 0; i < args.length; i++) { //趟数
for (int j = 0; j < args.length - 1 - i; j++) { //比较次数
if (args[j] > args[j + 1]) {
swap(args, j, j + 1);
}
}
}
}
3、冒泡排序的优化
我们来看这个序列的排序{2,1,3,4,5,6,7,8,9}如果用上面的排序算法,当i=0的时候交换一次之后,这个序列已经有序,但是程序依然会从i=0 遍历到i=args.length 。所以当i=1的时候没有进行任何的数据交换,就说明这个序列有序了,可以不用进行后面的循环操作了。为了实现这个想法,我没可以设置一个标志位,flag来控制循环的结束。
/**
* 冒泡排序的优化
*
* @param args
*/
public static void sort4(int[] args) {
boolean flag = true; //用flag来做标记为,用来标识当前序列是否发生了数据交换
for (int i = 0; i < args.length && flag; i++) {
flag = false;
for (int j = args.length - 2; j >= i; j--) { //从后往前循环
if (args[j] > args[j + 1]) {
swap(args, j, j + 1);
flag = true; //发生了数据交换设置为true
}
}
}
}