初学编程总是会遇到冒泡排序,在网上想找到冒泡排序的代码很容易,代码一般都是这样。
public static void main(String[] args) {
int[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length -i -1 ; j++) {
if (a[j] > a[j + 1]) {
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for (int i : a) {
System.out.print(i+" ");
}
}
代码中的i控制的是外层循环,也就是比较多少趟,而j是控制搬哪个数,从哪搬到哪,每一趟都会把最大的数搬运到最后面。
但是仔细想想,咦?冒泡难道不应该是往上走吗?怎么就把最大的搬到最后?如果想每次都把最小的搬到最上面代码应该是什么样的了?
只是改变一下搬运的方向,和原来的代码应该不会差太多。要改的话首先要弄明白是如何循环搬运的。
代码中的i代表的是搬运的趟数,每一趟都是把最大的搬运到最后的那个位置,那么我们要做的就是把每一次最小的搬运到最前面,搬运的总趟数是不会变的,所以循环中的i及上面的定义部分的代码不用改动。
public static void main(String[] args) {
int[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
for (int i = 0; i < a.length - 1; i++) {
}
}
每一趟的搬运都是要将整个数据遍历到,在之前的大数沉底的时候j是从0开始的,比到后面,那么如果要把小的数搬到前面则要从最后一个数开始比,比到前面来。所以j的初始值一个是a.length - 1,
因为数组是从0开始,最后一个数就是长度减一,而每次循环j就要从自增变成自减。
public static void main(String[] args) {
int[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
for (int i = 0; i < a.length - 1; i++) {
for (int j = a.length - 1; j > 0 ; j--) {
}
}
}
然后是比较部分:
既然j是数组的最后一个数字,那么就应该和它前面的一位比较也就是a[j-1],如果j比较小就换到前面去。最后加上打印语句就完成了。
public static void main(String[] args) {
int[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
for (int i = 0; i < a.length - 1; i++) {
for (int j = a.length - 1; j > 0 ; j--) {
if (a[j] < a[j - 1]) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
for (int i : a) {
System.out.print(i+" ");
}
}
这个样子答案是没有什么问题,但是我细心的朋友发现每一趟都是要比较9次,而传统的冒泡比较的次数是逐次递减,也就是每一趟搬完成之后,那个数字在下一次的搬运中不会被比较,而我这个写法每次都是从头比较到末尾,时间复杂度变大了。
但是我只是把搬运的方向改变了,按道理来讲时间复杂度不会有改变。玄机应该在这个j的比较上面,因为j控制的是每一趟比较的次数。
当1从a[9],变到a[0],之后它的位置就确定了,应该可以不被比较了,所以j应该是小于i而不是小于0。
public static void main(String[] args) {
int[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
for (int i = 0; i < a.length - 1; i++) {
for (int j = a.length - 1; j > i ; j--) {
if (a[j] < a[j - 1]) {
int temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
for (int i : a) {
System.out.print(i+" ");
}
}
到这里,结束了沉底到冒泡。算法这个东西写不出来的时候是真滴让人脑阔疼,写出来了也是真滴开心。