特别说明:
对于算法,重在理解其思想、解决问题的方法,思路。因此,以下内容全都假定待排序序列的存储结构为:顺序存储结构。
冒泡排序思想
冒泡排序与插入排序、简单选择排序一样,都是比较简单的一类排序算法。假设待排序序列为 ,则冒泡排序算法思想如下:
01.设置 = - 1 (注:0 - 1, 用于标记外层循环迭代);
02.如果 = 0,则排序结束,退出;
03.设置 = 0 (注:0 , 用于标记内层循环迭代);
04.如果 = ,跳转并执行 09 步骤 (即:该趟冒泡排序的内循环操作结束);
05.比较 与 ;
06.如果 ,则交换 与 ;
07.设置 = + 1,跳转并执行 04 步骤;
08.设置 = + 1,跳转并执行 02 步骤 (即:进入下一趟冒泡排序处理);
冒泡排序分析
冒泡排序是比较简单的一类排序算法,其时间复杂度为 ,空间复杂度为 ,该算法是属于交换类别的排序算法。与直接插入排序算法类似,如果待排序的序列在已经有序(或者基本有序)的情况下,冒泡排序是可以通过优化(或称之为改进,可能更为适合),其时间复杂度是有可能达到 的,具体做法是在一趟冒泡处理过程中,用一个标记设置在该趟处理过程中,第一个产生交换的元素位置,则在下一趟冒泡处理过程中,即可直接从该位置开始。因为该位置之前没有交换,则说明它们已经是有序的,故不需要对这些元素做冒泡排序处理 (具体可见下面编码实现参考)。
冒泡排序实现
下面是经过改进后的冒泡排序算法编码实现 (仅供参考):
1 // 2 // summary : 冒泡排序.(带优化游标的版本) 3 // in param : seqlist 待排序列表.同时也是排完序列表. 4 // in param : nLen 列表长度 5 // out param : -- 6 // return : -- 7 // !!!note : 01.以下实现均假设一切输入数据都合法.即:内部不对参数全法性进行校验,默认它们全都合法有效. 8 // 02.排序开始前 seqlist 是无序的,排序结束后 seqlist 是有序的. 9 void bubble_sort(int seqlist[/*nLen*/], const int nLen) { 10 auto nInnerIdx = 0; 11 auto nFlag = 0; 12 auto nOuterIdx = nLen - 1; 13 for (auto nOuterIdx = nLen - 1; nOuterIdx > 0; nOuterIdx = nFlag) { 14 for (nFlag = 0, nInnerIdx = 0; nInnerIdx < nOuterIdx; ++nInnerIdx) { 15 if (seqlist[nInnerIdx] > seqlist[nInnerIdx + 1]) { 16 swapTwoItems(seqlist, nInnerIdx, nInnerIdx + 1); 17 nFlag = nInnerIdx; 18 } 19 } 20 } 21 }