第二篇关于排序的 依然是交换类的排序 --冒泡排序 (相邻比序法)
数据结构的时候学过 现在比较喜欢写博客 虽然简单基础 但是还是写于此
冒泡排序基本思想就是 :反复扫描待排序的数组 ,在扫描的过程中顺次比较相邻的两个元素的大小,若逆序则交换位置
上代码:
/**
* 标志性的两层循环 第二层循环是确定排序的数组范围 ,所以第一层循环每一轮都是将第二层确定的范围中最大的数移到最后
*
* 第一层循环次数是 length-1 第二层循环次数是 length-1-i
*
* @author laowang
*/
public class Test {
private static int[] data;
/**
* 冒泡排序 未 精简版 此时比较次数仍然是n*(n-1)/2,所以时间复杂度仍是O(n^2),失败的算法
*/
public static void Sort_Bad() {
int temp; // 坚决不能定义在for循环内部 ,会加大空间复杂度
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9 - i; j++) {
if (data[j] > data[j + 1]) {
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
}
/**
* 改进版冒泡排序 可以算法在最佳情况的时间复杂度降到:O(n)
*/
public static void Sort_Better() {
int temp;
boolean isSorted = false; // 此变量表示数组是否已经有序 ,这就是对最优情况的优化 ,当数组已经有序时
// ,不需要继续进行循环
for (int i = 0; i < 9 && !isSorted; i++) { // 如果一轮第二层循环结束都没有进行过交换
// 说明数组已经有序,所以一旦isSorted ==
// true 排序结束
isSorted = true; // 第一层循环每次都需将它赋值为false
for (int j = 0; j < 9 - i; j++) {
if (data[j] > data[j + 1]) {
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
isSorted = false;
}
}
}
}
/**
*
* 用增强for循环输出当前数组
*/
public static void PrintData() {
for (int i : data) {
System.out.print(" " + i);
}
System.out.println("");
}
public static void main(String[] args) {
data = new int[10];
System.out.println("输入十个数 进行冒泡排序");
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 10; i++) {
data[i] = scanner.nextInt();
}
// Sort_Bad();
Sort_Better();
PrintData();
scanner.close();
}
}
冒泡排序空间复杂度为:O(1),平均时间复杂度为:O(n^2)
冒泡排序算法最坏情况是:待排序数组是完全逆序的,此时第i趟冒泡排序共需进行n-i次比较,3(n-i)次移动,经过n-1趟排序后
* 总的比较次数是:n*(n-1)/2,移动次数是:3*n*(n-1)/2;所以时间复杂度为O(n^2),
最好的情况是数组完全有序,所以没有交换数组元素这个过程。 但是我上面写了两个版本,当然第一个版本是普通的,时间复杂度是O(n^2);
第二个版本是进行了优化:在循环过程中,如果数组已经有序,则循环结束, 时间复杂度为O(n)。
冒泡到此结束,下节是直接插入排序,(我最近怎么这么想写算法呢 ,看来是幡然悔悟了~~~~)