简述
冒泡排序通过反复遍历要排序的列表,比较每对相邻项,并以升序或降序的方式交换它们。重复操作列表,知道不需要交换为止。
复杂度
名称 | 最好 | 平均 | 最差 | 空间 | 稳定性 |
冒泡排序 | n | n2 | n2 | 1 | 是 |
理解
- 冒泡排序,有
n
个数字,就要进行n
次大循环- 每次大循环,会找到所有数里面的最大或最小的数并放到正确的位置上
- 大循环里面小循环,本质上就是从下标
0
到当前未处理完成的最大下标之间进行循环,任务是找到最大或最小的目标,当找到了,当前未处理完成的最大下标的值就会相应缩小 length-i-1
的本质应该是length-1-i
length-1
代表的是一组待处理数组的最大下标- 这个最大下标之所以要
-i
,是因为完成了i
次大循环,代表着有i
个数字已经位于正确的位置,它不需要再被处理
初步实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void BubbleSort(int array[],int length) { for (int i = 0; i < length - 1; ++i) { for (int j = 0; j < length - i - 1; ++j) { int temp = 0; if (array[j] > array[j + 1]) { temp = array[j]; array[j] = array[j + 1]; array[j + 1] = temp; } } } } |
优化版1.0
经过一定次数的排序,数组可能已经处于完成排序的状态,但是,冒泡排序的流程还没走完,所以它还会继续排序,直到走完流程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void BubbleSort(int array[],int length) { for(int i = 0;i < length - 1; ++i) { bool isSorted = true; for(int j = 0;j < length - i -1; ++j) { int temp = 0; if(array[j] > array[j+1]) { temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; isSorted = false;//因为有元素发生了交换,所以不是有序的 } } if(isSorted) break; } } |
优化版2.0
存在一种情况,数组在排序之前,有部分区间就是有序的序列。针对这种现象优化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void BubbleSort(int array[],int length) { //记录最后一次交换的位置 int lastExchangeIndex = 0; //无序数列的边界 int sortBorder = length - 1; for(int i = 0;i < length - 1; ++i) { //有序标记 bool isSorted = true; for(int j = 0;j < sortBorder; ++j) { int temp = 0; if(array[j] < array[j+1]) { temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; //因为有元素交换,所以是无序的 isSorted = false; //更新最后一次交换元素的位置 lastExchangeIndex = j; } } sortBorder = lastExchangeIndex; if(isSorted) break; } } |
鸡尾酒排序
简述
鸡尾酒排序,是基于冒泡排序的一种升级排序法。
区别
- 冒泡排序
- 每一轮都是从左到右来比较元素,进行单向的位置交换的。
- 鸡尾酒排序
- 每一轮的元素比较和交换过程都是双向的。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
void BubbleSort(int array[],int length) { int temp = 0; for(int i = 0;i < length/2; ++i) { //有序标记 bool isSorted = true; //奇数轮,从左向右比较和交换 for(int j = 1;j < length -i -1; ++j) { if(array[j] > array[j+1]) { temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; //有元素交换,所以不是有序的,进行标记 isSorted = false; } } if(isSorted) break; //偶数轮之前,重置标记 isSorted = true; //偶数轮,从右往左比较和交换 for(int j = length -i -1;j > i; --j) { if(array[j] < array[j-1]) { temp = array[j]; array[j] = array[j-1]; array[j-1] = temp; //有元素交换,所以不是有序的,进行标记 isSorted = false; } } if(isSorted) break; } } |
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 查找_顺序查找05/09
- ♥ 数学知识模板03/09
- ♥ 狄克斯特拉算法06/29
- ♥ 数据结构_二叉树节点10/16
- ♥ 排序_计数排序05/08
- ♥ 动态规划_最长公共子序列09/05