写在前面
很早就想系统梳理所接触的所有算法,但是只是存在于一个想法阶段,懒惰使人遗忘不是么。作为一个软件开发人员,绕不开算法与数据结构,既然绕不开,何不逐一分析学习透彻,与君共勉之。
冒泡排序算法(Bubble Sort)作为排序算法较为基础的一种,也是比较好理解的,所以先从这里开始总结排序算法。排序算法也根据实际的算法思路分为插入排序、选择排序、交换排序、归并排序,冒泡属于交换排序的一种。
算法思路
冒泡排序,顾名思义就是像水泡上浮一样,大大小小...
冒泡排序就是从数组的首个元素出发,单步向后移动,一一与后面的元素进行比较,遇到比自己小的元素即进行交换。进行完一轮后将最大值放到最后一位。
5 | 2 | 4 | 1 | 3 | |
step1 | 2 | 5 | 4 | 1 | 3 |
step2 | 2 | 4 | 5 | 1 | 3 |
step3 | 2 | 4 | 1 | 5 | 3 |
step4 | 2 | 4 | 1 | 3 | 5 |
然后再进行下一轮
2 | 4 | 1 | 3 | 5 | |
step1 | 2 | 4 | 1 | 3 | 5 |
step2 | 2 | 1 | 4 | 3 | 5 |
step3 | 2 | 1 | 3 | 4 | 5 |
next round:
2 | 1 | 3 | 4 | 5 | |
step1 | 1 | 2 | 3 | 4 | 5 |
step2 | 1 | 2 | 3 | 4 | 5 |
直到所有都完成
1 | 2 | 3 | 4 | 5 | |
step1 | 1 | 2 | 3 | 4 | 5 |
以上图示中:红色代表原位置,绿色代表待比较位置,蓝色为排序完成位置。
引用动态图示:
C++示例代码
#include <iostream>
#include <vector>
using namespace std;
void bubble_sort(vector<int>& v)
{
int len = v.size();
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (v[j] > v[j + 1])
{
swap(v[j], v[j+1]);
}
}
}
}
int main()
{
vector<int> vec{4,2,11,1,5,65,88,43,12,3,4};
bubble_sort(vec);
system("pause");
return 0;
}
时间复杂度
从上述例子可以看出,不是每一次都必须进行交换,如果发现当前元素即为最小元素,则不必再与后面元素进行比较交换,所以在时间复杂度上存在两个极限:
最优的情况是不用交换排序,一开始一切都排序好了,只需要进行一次遍历即可,时间花销为:[n(n-1)/2]; 复杂度为O(n)
最差的情况就是排序的时候,全部从大到小逆序的,花销时间为[3n(-1)]/2,所以最差的情况下时间的复杂度是执行次数平方为O(n²)
空间复杂度
最优的空间复杂度,同样,就是不需要借用第三方内存空间,则复杂度为0。
最差的空间复杂度就是开始元素逆序排序,每次都要借用一次内存,按照实际的循环次数,为O(N)。
平均的空间负杂度为:O(1)。
注:动态图示引用自菜鸟教程