经历了大学一年,再回首重新审视冒泡排序,可以看的更透彻,更明朗一些。
其实整个中心思想在于,一个有序的排列中,一定不会存在逆序对,所以它一遍遍的遍历,让各个位置保证数字就位。版本A:
for(i=0;i<n-1;i++) { for(j=1;j<n-i;j++) { if(num[j]<num[j-1]) { temp = num[j]; num[j] = num[j-1]; num[j-1] = temp; } } }版本B: 在这里是对冒泡排序的又一步改进,冒泡排序实际上就是对逆序对的检验,而当逆序对不存在也就没有了继续遍历序列的必要了,所以只需要在循环添加一个判断的变量就好了。
for(i=0;i<n-1;i++) { judge = 0; for(j=1;j<n-i;j++) { if(num[j]<num[j-1]) { judge = 1; temp = num[j]; num[j] = num[j-1]; num[j-1] = temp; } } if(!judge) break; }版本C: 它是对这一个算法的又一改进,它是对于一种一般情况,而做出的改进,对于一个序列,它的前半段是乱序的,而后半段的元素是已经就位的,无需重排的,这也就意味着可以省略掉对于后半段元素的一次次的重复遍历,来节省时间,并且这种情况是比较常见的即使在最初情况下,整个序列都是乱序的,但是经过几次遍历后仍有可能出现这种情况。
hi = n; for(i=0;i<n-1;i++) { for(j=1;j<hi;j++) { if(num[j]<num[j-1]) { last = j-1; temp = num[j]; num[j] = num[j-1]; num[j-1] = temp; } } hi = last; }总而言之,这几种方案本身都是冒泡排序或者叫起泡排序,它们的效率最好情况下都是O(n),最坏的情况都是O(n^2) 经过优化,他们的差异在于一般情况下的效率。 还有一个额外的小问题,那就是稳定性: 稳定性是指如: 1 2 7a 4 7b 5 7c 排序后 1 2 4 5 7a 7b 7c(stable) 1 2 4 5 7a 7c 7b(unstable)
而很显然冒泡排序是稳定的,因为在遍历过程中两个元素的相互位置发生变化,只有当两个元素相邻且两个元素是逆序对。接下来介绍一种时间复杂度为O(nlogn)的算法
