2.冒泡排序

2.冒泡排序

2.1冒泡排序的思想和复杂度

冒泡思想

冒泡排序,顾名思义就是像气泡一样,大小不一的气泡会依次逐个交换位置,然后形成从小到大的顺序。冒泡排序可以从左向右冒泡,也可以从右向左冒泡,但正宗的冒泡是从右向左的。意思就是说如果要排成从小到大的顺序,就要从最右端向最左端扫描并交换。

时间和空间复杂度

时间复杂度如表所示

算法 平均情况 最好情况 最差情况
冒泡 O(N^2) O(N) O(N^2)

空间复杂度:O(1)

2.2冒泡排序的操作

假设有这样一个数组vec:

下标 0 1 2 3 4 5 6 7 8 9
数组 4 3 5 2 1 9 8 6 0 7

对这个数组进行冒泡排序,我们首先设定一个外层循环 i (0<i<N-1),循环次数为N=vec.size()。然后在每个外层循环的内层循环 j (i+1<j<N-1)中进行扫描。内层循环的目的是为了从右向左扫描,通过依次相邻比较的方式找到最小的数,放到数组vec的最左边i的位置上,下一次内循环之前i++,就不再扫描这个最小的数字了。外层循环的目的是为了保证排序完成后的每一个数字都是经过冒泡放在了正确的位置上,而不遗漏对每个数字的冒泡。

内层循环(i<j<number-1, j--)

可以通过下表理解内层循环中一次扫描中的交换:

指针 i j
原始数组 4 3 5 2 1 9 8 6 0 7
指针 i j-1 j
更新数组 4 3 5 2 1 9 8 6 0 7
指针 i j-1 j
更新数组 4 3 5 2 1 9 8 0 6 7
指针 i j-1 j
更新数组 4 3 5 2 1 9 0 8 6 7
指针 i j-1 j
更新数组 4 3 5 2 1 0 9 8 6 7
指针 i j-1 j
更新数组 4 3 5 2 0 1 9 8 6 7
指针 i j-1 j
更新数组 4 3 5 0 2 1 9 8 6 7
指针 i j-1 j
更新数组 4 3 0 5 2 1 9 8 6 7
指针 i j-1 j
更新数组 4 0 3 5 2 1 9 8 6 7
指针 i&j-1 j
更新数组 0 4 3 5 2 1 9 8 6 7

外层循环(0<=i<vec.size(), i++)

可以通过下表理解外层循环的交换:

指针 i
原始数组 4 3 5 2 1 9 8 6 0 7
指针 i
更新数组 0 4 3 5 2 1 9 8 6 7
指针 i
更新数组 0 1 4 3 5 2 6 9 8 7
指针 i
更新数组 0 1 2 4 3 5 6 7 9 8
指针 i
更新数组 0 1 2 3 4 5 6 7 8 9
指针 i
更新数组 0 1 2 3 4 5 6 7 8 9
...

到这里实际上已经排序完成了。

优化

为了提高冒泡排序的效率,我们在代码里加一个flag,用这个flag来检查是不是已经排序完成了。冒泡排序完成以后是不会再有数字交换的情况了,所以我们用flag来记录是否进行了交换,如果没有交换,那么我们就认为排序完成,不再进行外层循环。
OK, 可以上代码了。

2.3 C++代码###

#include <iostream>
#include <vector>
using namespace std;

class Sort
{
public:
    void bubble(vector<int> &vec)
    {
        int number=vec.size();
        vector<int> nullvec;
        if(number==0)return;
        bool flag=true;
        for(int i=0;i<number && flag;i++)
        {
            flag=false;
            for(int j=number-1;j>i;j--)
            {
                if(vec[j-1]>vec[j])
                {
                    exch(vec,j-1,j);
                    flag=true;
                }
            }
            show(vec);
        }
    }
    void show(vector<int> &vec)
    {
        for(int i=0;i<vec.size();i++)
        {
            cout << vec[i] << " ";
        }
        cout << endl;
    }
    vector<int> init()
    {
        vector<int> vec;
        int arr[10]={4,3,5,2,1,9,8,6,0,7};
//        int arr[10]={9,8,7,6,5,4,3,2,1,0};
        vec.insert(vec.begin(),arr,arr+10);
        cout <<"ori:"<<endl;
        show(vec);
        cout <<"-------------------"<<endl;
        return vec;
    }
    bool checkorder(vector<int> &vec)
    {
        for(int i=0;i<vec.size()-1;i++)
        {
            if(vec[i]>vec[i+1])return false;
        }
        return true;
    }
private:
    void exch(vector<int> &vec,int a,int b)
    {
        int tmp;
        tmp=vec[a];
        vec[a]=vec[b];
        vec[b]=tmp;
    }
};

int main()
{
    Sort sortob;
    vector<int> mvec=sortob.init();
    sortob.bubble(mvec);
    cout <<"------result-------"<<endl;
    if(sortob.checkorder(mvec))
        sortob.show(mvec);
    else
    {   cout << sortob.checkorder(mvec);
    }
    return 0;
}

输出结果:

image.png

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 常见问题: 对数组{5,18,21,1,3,62,7}进行从小到大的排序,使用冒泡排序算法。 1.什么是冒泡排序?...
    陈文洁945阅读 289评论 0 0
  • 总结一下常见的排序算法。 排序分内排序和外排序。内排序:指在排序期间数据对象全部存放在内存的排序。外排序:指在排序...
    jiangliang阅读 1,391评论 0 1
  • 之前给大家介绍的桶排序想必让大家狠狠的爽了一把给别人排成绩的乐趣哈哈,不过它只能给成绩排序,这些成绩如果对应着人呢...
    寒枝旧廊阅读 392评论 2 3
  • 冒泡排序 1.冒泡排序算法的运作如下:比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样...
    疯狂的喵喵阅读 328评论 1 2
  • 那天是升上初三的第二天,快要上课的时候,李天杰望了望门口,想看看即将教他们数学的老师是谁。 直到上课前的1分钟才有...
    烛影摇红_06ba阅读 1,559评论 2 4