对冒泡排序法的个人理解

下文全部以数组的从小到大排序为例,对象排序、从大到小排序同理。

冒泡排序法,是从数组的第一个数开始,依次向后比较相邻的两个数;前者比较大时,就将二者换位,这样一次遍历完成后,最大的数就在最后;之后再从第一个数开始向后比较(不比较最后一个数),依此类推。

选择排序法,是用数组的第一个数,依次和后面的数比较;后面的数小于第一个数时,将其置换到第一位,这样一次遍历完成后,第一个数就是最小的数;之后再从第二个数开始和后面比较,依此类推。

以前写冒泡排序法时,都是写完两个循环之后,用第一次外循环和最后一次外循环时比较的数组角标,来计算两个循环的初始值和条件表达式。今天觉得每次都要算一下这个好麻烦,然后想了想外循环和内循环的意义:

 1   for(i = 0; i < N-1; i++) {//内循环进行次数:数组长度-1
 2     //内循环:一次冒泡,循环完成后数组最后一个数是最大的数
 3     for(j = 0; j < N-i-1; j++) {//比较进行次数:数组长度-已完成排序数量-1(已完成排序数量=内循环已完成次数=i)
 4       if(buf[j] > buf[j+1]) {
 5         temp = buf[j];
 6         buf[j] = buf[j+1];
 7         buf[j+1] = temp;
 8       }
 9     }
10   }

每次内循环完成后,数组最后一个数就是最大的数,因此一共需要进行(数组长度-1)次内循环,所以外循环的条件表达式为 i<N-1 

每次内循环中,需要比较的次数为剩余需要排序的数量-1次(最后一个数不需要和后面的数比较);又因剩余需要排序的数量=数组长度-已完成排序的数量,而已完成排序的数量=内循环完成次数,所以每次内循环需要进行(数组长度-内循环已完成次数-1)次比较,所以内循环的条件表达式为 j<N-i-1 。

这样理解就简单多了。

同时,也可以据此计算出一次冒泡排序法需要比较的次数:N(N-1)/2次。(N-i-1(i从0到N-2)的累加和)。

总结一下:

对于外循环,我们只关心内循环需要进行的次数,也就是把最大的数放到最后这个操作重复的次数(N-1次),因此外循环为 for(i = 0; i < N-1; i++) ;

对于内循环,我们只关心每次内循环比较的次数,也就是每次把最大的数放到最后需要比较的次数(N-i-1次),因此内循环为 for(j = 0; j < N-i-1; j++) ;

至于是从小到大排序,还是从大到小排序,这些事情就交给比较环节去改变就可以了。

同样的,对于选择排序法,有:

外循环需要从第一个数向后遍历,直到倒数第二个数,因此一共需要进行(数组长度-1)次内循环,所以外循环的条件表达式为 i<N-1 ,外循环为 for(i = 0; i < N-1; i++) ;

每次内循环中,已完成排序数量为i,而每次内循环都是从当前还没完成排序的第一个数,向后遍历到数组结尾,因此内循环为 for(j = i; j < N-1; j++) 。

同时,也可以据此计算出一次选择排序法需要比较的次数:N(N-1)/2次。(N-i-1(i从0到N-2)的累加和)。

猜你喜欢

转载自www.cnblogs.com/cage666/p/10648767.html