7.冒泡排序(优化版本)

一般我们写冒泡排序时都会这么写:

void bubbleSort(T arr[], int n){
    for(int i = 0; i < n-1; i++){
        for(int j = 0; j < n-1-i; j++)
            if(arr[j] > arr[j+1])
                swap(arr[j],arr[j+1]);
    }
}

经过优化的冒泡排序是这样的:

void bubbleSort(T arr[], int n){
    bool swapped;
    do
    {
        swapped = false;
        for( int i = 0; i < n-1; i++ ){
            if( arr[i] > arr[i+1] ){
                swap(arr[i], arr[i+1]);
                swapped = true;
            }
        }
    n--;
    }while(swapped)
}

现在我们分别用最差和最优两种情况来分别衡量这两个版本冒泡排序的性能。

首先看最差情况,也就是对一个完全无序的数组进行排序,例如[4,3,2,1].
对于一般版本 需要经过(1+2+3+...+n-1)=n(n-1)/2 次比较操作(即if操作).
对于优化版本 同样需要经过这么多次比较.

我们来测试一下:

test.cpp:
#include <iostream>

using namespace std;

template<typename T>
void bubbleSort_low(T arr[], int n){
    for(int i = 0; i < n-1; i++){
        for(int j = 0; j < n-1-i; j++)
        {
            cout << 1 ;
            if(arr[j] > arr[j+1])
                swap(arr[j],arr[j+1]);
        }
    }
    cout << endl;
}

template<typename T>
void bubbleSort_advance(T arr[], int n){
    bool swapped;
    do{
        swapped = false;
        for( int i = 0; i < n-1; i++ ){
            cout << 2 ;
            if( arr[i] > arr[i+1] ){
                swap( arr[i], arr[i+1] );
                swapped = true;
            }
        }
        n--;
    }while(swapped);

    cout << endl;
}
int main()
{
    int a1[4] = {1,2,3,4};
    int a2[4] = {1,2,3,4};
    int b1[4] = {4,3,2,1};
    int b2[4] = {4,3,2,1};
    bubbleSort_low(b1,4);
    bubbleSort_advance(b2,4);
    return 0;
}

发现两个版本的比较都执行了6次比较 ,将4带入n(n-1)/2这个公式算也是6

也就是说二者在最差情况下的性能是基本相同的(忽略细枝末节的一些影响),其时间复杂度都是O(n^2)级别的。

再来看最优情况,也就是数组完全有序的情况,用[1,2,3,4]测试.

int main()
{
    int a1[4] = {1,2,3,4};
    int a2[4] = {1,2,3,4};
    int b1[4] = {4,3,2,1};
    int b2[4] = {4,3,2,1};
    bubbleSort_low(a1,4);
    bubbleSort_advance(a2,4);
    return 0;
}

我们这样得到的结果是:


发现 low版本执行了6次,advance版本执行了3次
也就是说在最优情况下,第一种版本也是执行了n(n-1)/2 次,时间复杂度依旧是O(n^2).
但第二种版本,i从0迭代到n-2 共执行了n-1次比较操作,在这里就是3次,时间复杂度为O(n).

稍微改一下,加深下理解:

int main()
{
    int a1[4] = {2,1,3,4};
    int a2[4] = {2,1,3,4};
    int b1[4] = {4,3,2,1};
    int b2[4] = {4,3,2,1};
    bubbleSort_low(a1,4);
    bubbleSort_advance(a2,4);
    return 0;
}

得到的结果是这样的:


advance版本执行了5次,第一轮for循环i从0到n-2,执行3次if操作,然后将swapped改为true,接着还是要进到do while语句里,第二轮for循环i从0到n-3,执行2次if操作,这一趟的作用是检查看还有没有逆序对,发现没有就退出了,共执行了5次.
通过这个例子的补充,我们知道了advance版本的冒泡排序不管是完全有序,还是完全无序,它都要执行i从0到n-1的遍历操作来检查一遍是否有逆序对的存在.

小结:
最差情况:
一般冒泡排序 O(n^2)
优化的冒泡排序 O(n^2)

最优情况:
一般冒泡排序 O(n^2)
优化的冒泡排序 O(n)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 一、 单项选择题(共71题) 对n个元素的序列进行冒泡排序时,最少的比较次数是( )。A. n ...
    貝影阅读 9,065评论 0 10
  • 多少日子尘与土 多少悲伤朝与暮 多少想念甜与苦 一页页 写成书 正当午 你听 我读 多少渴望来与去 多少欢笑散与聚...
    妮妮雅阅读 233评论 0 3
  • DAY19: 需要觉察--力量 不知不觉,已坚持写了19天的需要觉察。想给自己一个赞,也问了问自己,是什么力量让我...
    沈子暄阅读 129评论 0 0
  • 上班以来,时间感觉明显没有以前充裕,上学除了国家法定节假日之外还会有寒暑假,另外可以课业不忙的时候还能请个假出去。...
    小清读书阅读 321评论 0 1
  • 1,这个人有一个怎么样的理想家庭?他的房子妻子女儿和儿子扮演什么样的角色。 答:他的家人都是靠金钱来维持关系,家...
    顾音阅读 459评论 0 0