标签:
基本原理:
对一元素个数为n的数列进行扫描,同时逐一比较相邻的两个元素,按照所需的排序原则(顺序或逆序)对不满足要求的一组元素进行置换,一次扫描可以在得出一个当次扫面元素中最大或者最小的元素,然后对剩下的n-1个元素再进行同样的扫描与比较。在进行了n-1次扫描后,得到最终排好序的数列。因此冒泡排序的时间复杂度为o(n*n)。
基本实现:
按照冒泡排序的思想,实现如下:
bool BubbleSort(int arrData[], int n) { if(!arrData || n <= 0) return false; for(int i = 0; i < n-1; ++i) { for(int j = n-1; j > i; --j) //为更形象的贴近冒泡的含义,进行逆序扫描, { //使得每次扫描将最小的值放置在数组的最前端 if(arrData[j-1] > arrData[j]) { int temp = arrData[j]; arrData[j] = arrData[j-1]; arrData[j-1] = temp; } } } return true; }
改进实现一:
在基本实现中,只是根据数列的元素个数,按照原理机械的进行循环比较,没有考虑到过程中数列的状态,比如可能数列在结束循环之前,已经达到了要求的效果,但是还在进行没有必要的循环,因此造成效率上的损失。所以进行了如下改进,具体思想是,如果在某一次扫描过程中,没有发生一次置换操作,则实际数列已经排序完成。此时可以跳出循环,结束操作。
bool BubbleSortEx1(int arrData[], int n) { if(!arrData || n <= 0) return false; bool bSwaped = true; for(int i = 0; i < n-1; ++i) { bSwaped = false; for(int j = n-1; j > i; --j) { if(arrData[j-1] > arrData[j]) { int temp = arrData[j]; arrData[j] = arrData[j-1]; arrData[j-1] = temp; bSwaped = true; } } if(!bSwaped) break; } return true; }
改进实现二:
在”改进实现一“中,只是对外面的for循环做了优化,在一定条件下减少了外面for循环的次数。但是对于内部的for循环,依旧是进行机械式的操作。假设如下情况:某次扫描需要对n个元素进比较,内部的for要循环n-1次,但实际发现从第j次开始,就没有发生置换了。也就是说从数列的第j到第n个元素,已经排序好了。但是如果进行机械式的处理,在下一次扫描时,还是会对j到n-1之间的元素进行扫描,但这些元素已经排序好了,只是进行了无意义的操作,同样影响了效率。因此有了如下改进:
bool BubbleSortEx2(int arrData[], int n) { if(!arrData || n <= 0) return false; int i = 0; while(i < n-1) { int pos = n-1; for(int j = n-1; j > i; --j) { if(arrData[j-1] > arrData[j]) { int temp = arrData[j]; arrData[j] = arrData[j-1]; arrData[j-1] = temp; pos = j; } } i = pos; } return true; }
以上实现增加了一个pos变量用来记录每次扫描最后一次发生置换时的元素编号,那么对于下一次扫描,此编号之前的数列已经排序好了。所以只需要扫描n-1到pos之间的元素即可。当pos等于n-1时,表示数列全部排序完毕,跳出while循环。
标签:
原文地址:http://www.cnblogs.com/DeafeningZhao/p/4482124.html