顾名思义,冒泡就像水底下往上冒泡泡,泡泡在上升过程中越来越大,所以说我们最终的得到的数列是从大到小的。
冒泡排序的思想就是利用的比较交换,利用循环将第 i 小或者大的元素归位,归位操作利用的是对 n 个元素中相邻的两个进行比较,如果顺序正确就不交换,如果顺序错误就进行位置的交换。通过重复的循环访问数组,直到没有可以交换的元素,那么整个排序就已经完成了
示例
接下来我们设一个数列,初始数列为:3,4,1,5,2;(图片借用大佬的)我们排序的目的是通过好几步来达到由下向上的从大到小的排序结果,图片解释:红色代表当前进行比较的对象,绿色代表已经达到目标位置
初始位置如图
第一遍过程
我们选择最底下那个3与上面进行比较发现4>3,所以两个进行位置调换,此时3继续与上面的1进行比较发现3<1所以我们把3先放一放
然后将1与5进行比较,1<5那么进行位置调换,1再与2进行比较,1<2那么继续位置调换
最后,我们知道我们需要进行四次比较
第二遍过程
我们由第一遍结尾知道目前顺序是4,3,5,2,1;我们还是从下往上比较
4>3,不动;3<5,位置调换;3>2,不动;
第三遍过程
第二遍排序结果4,5,3,2,1;
4<5,位置调换;4>3,不动
第四遍过程
第三遍结果5,4,3,2,1;
虽然我们眼看是已经排好序了,但是程序还是会继续进行比较
5>4,不动
总结
冒泡排序算法是稳定,原因是:冒泡排序只是进行两数之间的大小比较,如果相邻的两个数是相等的那么他就会简单相邻不会再进交行换
原始冒泡排序就是上面演示的,我们知道第四遍演示的时候其实这一遍是多余的,复杂度为O(n^2)
我们可以进行优化就是将这一边多余的比较去掉,复杂度就降为O(n)
代码实现
原始代码
#include<bits/stdc++.h>
using namespace std;
void bubblesort(int a[],int len) {
int temp;
for(int i=0; i<len-1; i++)
for(int j=0; j<len-1-i; j++) {
if(a[j]>a[j+1]) {
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
int main() {
int a[]= {3,4,1,5,2},l;
l=sizeof(a)/sizeof(a[0]);
bubblesort(a,l);
for(int i=0; i<l; i++) cout<<" "<<a[i];
return 0;
}
我们想要进行优化,那么我们可以在冒泡排序分函数里面加上一个flag,用来记录是否已经排好序,如果已经排好序那么我们直接返回就可
优化代码
#include<bits/stdc++.h>
using namespace std;
void bubblesort(int a[],int len) {
int temp;
int flag=0;
for(int i=0; i<len-1; i++){
for(int j=0; j<len-1-i; j++) {
if(a[j]>a[j+1]) {
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
flag=1;//不是有序的,即为1
}
}
if(flag==0) return;
}
}
int main() {
int a[]= {3,4,1,5,2},l;
l=sizeof(a)/sizeof(a[0]);
bubblesort(a,l);
for(int i=0; i<l; i++) cout<<" "<<a[i];
return 0;
}