思想
首先要明确的是,已排序序列在后,待排序序列在前,第一轮的待排序序列就是整个序列;每一轮都从待排序序列首部开始,比较相邻元素,如果前一个元素比后一个元素大,则交换两元素的位置,这么一轮下来,本轮最大的那个元素就到了末尾,成为已排序序列,待排序序列的元素个数相应减1,不断重复,最终达到完全有序
代码实现
普通版:
void sortBubble(vector<int>& nums) { int n = nums.size(); for (int count = 0; count < n - 1; ++count)//count表示已经有count个最大元素在末尾,循环n-1次 { for (int i = 0; i <= n - 2 - count; ++i) { if (nums[i] > nums[i + 1]) swap(nums[i], nums[i + 1]); } } }
改良版:
加入change变量,一轮下来,元素有交换的话,change为true,没有交换,则为false;
一轮下来都没有元素交换的话,那么下一趟就肯定不会有交换了,那就提前跳出循环吧;
void sortBubble(vector<int>& nums) { int n = nums.size(); for (int count = 0; count < n - 1; ++count)//count表示已经有count个最大元素在末尾,循环n-1次 { bool change = false; for (int i = 0; i <= n - 2 - count; ++i) { if (nums[i] > nums[i + 1]) { swap(nums[i], nums[i + 1]); change = true; } } if (change == false) break; } }
单循环版
通过在循环体内部改变循环变量 i 和循环中止变量的值来实现单循环冒泡,其实就是把双循环展开成单循环,没什么很大的不同
void sortBubble(vector<int>& nums) { int times = nums.size() - 1; bool change = false; for (int i = 0; i < times; ++i)//循环n-1次 { if (nums[i] > nums[i + 1]) { swap(nums[i], nums[i + 1]); change = true; } if (i == times - 1)//最后一次时 { if (change == false) break; i = -1;//等会for循环会++i,i变为0 --times; change = false; } } }
时间复杂度
最好情况O(n):本身有序,比较完第一轮后就不用比较了,比较次数为n-1次
最坏情况O(n2):本身逆序
平均情况O(n2)
空间复杂度
O(1)
稳定性
都是对相邻元素交换,这种相邻关系可以保证相同元素排序前后的相对顺序不变,所以是稳定的