冒泡排序
算法思路
-
升序排列:
- 从左到右(或右到左)比较相邻的元素,如果当前元素比下一个元素大(或者小),就交换他们两个。
- 对下一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,本轮排序完成后得到无序部分中的最大元
素,此时这个最大元素和之前的已经排序的部分,组成新的有序部分 - 针对所有的无序元素重复以上的步骤,直到某一轮没有发生元素交换则说明排序完成
-
降序排列:
- 从左到右(或右到左)比较相邻的元素,如果当前元素比下一个元素小(或者大),就交换他们两个。
- 对下一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,本轮排序完成后得到无序部分中的最大元
素,此时这个最大元素和之前的已经排序的部分,组成新的有序部分 - 针对所有的无序元素重复以上的步骤,直到某一轮没有发生元素交换则说明排序完成
例:使冒泡法升序排列8,1,6,3,2,4
从左到右进行排序:
第一轮:
第二轮:
第三轮:
第四轮:
本轮中没有发生元素交换,就表示剩下的元素都是有序的,所以所有元素已经都是有序的了。
代码实现
bool BubbleSort(int * pUnSortAry, int nArySize) { if (pUnSortAry == nullptr || nArySize <= 0) { return false; } bool bFlag = false; for (int iIndex = 0; iIndex < nArySize; iIndex++) { for (int jIndex = 0; jIndex < nArySize - iIndex -1; jIndex++) { if (pUnSortAry[jIndex] > pUnSortAry[jIndex + 1]) { int nTemp = pUnSortAry[jIndex]; pUnSortAry[jIndex] = pUnSortAry[jIndex + 1]; pUnSortAry[jIndex + 1] = nTemp; bFlag = true; } } if (!bFlag) { break; //如果内存for循环中一次交换也没有发生,则说明所有元素已经有序 } } return true; }
测试代码:
void PrintData(int*pAry, int nSize) { for (int jIndex = 0; jIndex < nSize; jIndex++) { printf("%d ", pAry[jIndex]); } printf("\r\n"); } int main() { srand(time(NULL)); int nArry[20] = { 0 }; for (int jIndex = 0; jIndex < 10; jIndex++) { for (int iIndex = 0; iIndex < sizeof(nArry) / sizeof(nArry[0]); iIndex++) { nArry[iIndex] = rand() % 150; } printf("排序前:"); PrintData(nArry, sizeof(nArry) / sizeof(nArry[0])); BubbleSort(nArry, sizeof(nArry) / sizeof(nArry[0])); printf("排序后:"); PrintData(nArry, sizeof(nArry) / sizeof(nArry[0])); } }
测试结果:
时间复杂度分析
核心部分代码如下,假设待排序元素有n个
//执n次 for (int iIndex = 0; iIndex < nArySize; iIndex++) { //执行1+2+.....+n次 for (int jIndex = 0; jIndex < nArySize - iIndex -1; jIndex++) { //执行1+2+.....+(n-1)次 if (pUnSortAry[jIndex] > pUnSortAry[jIndex + 1]) { //执行(1/n)*(1+2+3...+n-1) int nTemp = pUnSortAry[jIndex]; pUnSortAry[jIndex] = pUnSortAry[jIndex + 1]; pUnSortAry[jIndex + 1] = nTemp; bFlag = true; } } //执行n次 if (!bFlag) { //执行一次 break; //如果内存for循环中一次交换也没有发生,则说明所有元素已经有序 } }
平均时间复杂度为:T(n) =n+n+(1+2....+n) + (1+2....+(n-1)) + (1/n)(1+2+3...+n-1))
= 2n + 2(1+2...+n) - n + (1/n)*(1+2+3...+n-1 + n) -1
= n + n(1+n) + (1/2n)*n(1+n) -1
= n^2 + (5n)/2 -1/2
= O(n^2)
当元素已经是有序的情况下时间复杂度为T(n)=O(n)
稳定性
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元
素之间。所以,如果两个元素相等,则不会进行交换如果两个相等的元素没有相邻,那么即使通过前面的两两
交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排
序算法。