背景:冒泡算法是一个十分基础的算法,奈何自己脑子不好使,总也记不住,故做此文章,以便记忆。
理解:冒泡算法的官方说明就不写了,通俗的理解就是每一轮进行--相邻两两比较--并把---最大的那个数----找出来放在最后;因为每一轮循环都会得到一个最大的数冒出来,所以称之为冒泡算法;
写代码前有两点要理解:
1. 整个数组完成排序需要进行n-1轮比较:例如
int a[] = {5, 3, 9, 6, 2};
长度为5 (a.length = 5)的数组a,每一轮比较会得出一个最大值,
那么完成所有排序,就需要进行n-1(数组a来说,就需比较4次)轮比较,
因为最后一个数没必要在比较了;
2 . 每一轮找到最大的数,需要进行n-1次比较:
int a[] = {5, 3, 9, 6, 2};
如果长度为5,一轮循环比较中需要比较4次,就可得到最大值了;
因为这个数跟自己是不需要比较的;
代码实现与理解:(理论不够,代码来凑)网上有多种写法,最初不知道哪一种是正确的,
其实原理理解了,写法就不重要了,反正都叫冒泡排序
1. 初级实现:
int a[] = {5, 3, 9, 6, 2};
int temp;
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 5,3,9,6,2
}
// 冒泡排序
for (int i = 0; i < a.length - 1; i++) {
// 最外层控制多少轮循环(此处为a.length - 1,就是4次循环)
for (int j = 0; j < a.length - 1; j++) {
// 里层控制多少次比较(此处为a.length - 1,就是4次循环,不做优化的)
if (a[j] > a[j+1]){
// 如果前一个数比后一个数大,则进行数据交换
temp =a [j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Log.i("chy1234","===================分割线=======================");
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 2,3,5,6,9
}
2. 对于内层查找最大数的循环次数进行优化,因为每一次都会找到一个最大值,
所以后续的比较就不用跟最大值比较了;所以内层循环的次数是递减的,第一轮是4次;
第二轮是3次...
int a[] = {5, 3, 9, 6, 2};
int temp;
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 5,3,9,6,2
}
// 冒泡排序
for (int i = 0; i < a.length - 1; i++) {
// 最外层控制多少轮循环(此处为a.length - 1,就是4次循环)
for (int j = 0; j < a.length - 1 - i; j++) {
/**
* 里层控制多少次比较,此处为a.length - 1 - i ,
* 就是4,3,2,1次循环,依次递减的;
* 因为每次循环都找到一个最大值,所以接下来的循环就不用和找出的最大值进行比较了
* 第1次i=0, 里面循环4次;第2次i=1, 里面循环3次就可以;
* 第3次i=2, 里面循环2次;第4次i=3, 里面循环1次就可以;
* 至此,执行完毕
*/
if (a[j] > a[j+1]){
// 如果前一个数比后一个数大,则进行数据交换
temp =a [j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Log.i("chy1234","===================分割线=======================");
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 2,3,5,6,9
}
3. 原理同2,只不过实现方式不一样,算的上是2上的另一种写法
int a[] = {5, 3, 9, 6, 2};
int temp;
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 5,3,9,6,2
}
// 冒泡排序
for (int i = a.length - 1; i > 0; i--) {
/**
* 最外层控制多少轮循环(此处为a.length - 1,就是4次循环)
* 此时i=4, i=3, i =2, i =1依次递减
*/
for (int j = 0; j < i; j++) {
/**
* 里层控制多少次比较,此处为 i ,
* 就是4,3,2,1次循环,依次递减的;
* 因为每次循环都找到一个最大值,所以接下来的循环就不用和找出的最大值进行比较了
* 第1次i=4, 里面循环4次;第2次i=3, 里面循环3次就可以;
* 第3次i=2, 里面循环2次;第4次i=1, 里面循环1次就可以;
* 至此,执行完毕
*/
if (a[j] > a[j+1]){
// 如果前一个数比后一个数大,则进行数据交换
temp =a [j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
Log.i("chy1234","===================分割线=======================");
for (int i=0;i < a.length;i ++){
Log.i("chy1234","====="+a[i]); // 2,3,5,6,9
}
总结: 以前固执的认为冒泡排序仅仅是一种写法,对于多种不同的写法存在疑惑;其实算法就是理解,理解了,至于实现方式,只要用到了冒泡的原理,那么都可以说成是冒泡算法