冒泡排序解读及优化

冒泡排序是选择排序中最为简单的一种,也是最为基础的一种。

他的规则是将第一个元素与第二个比较,比较后移动元素,再用第二个与第三个比较,直至最后一个元素,这是完成一趟排序,将最大的元素排到了最后。依此进行第二趟,第三趟直至排序完成。

先看下实际例子:

一般情况:

i 原序列:10  3   7    8   5   2   1   4   9   6     交换范围

1   1遍:  3   7    8   5   2   1   4   9   6   10  [0—10-1)

2   2遍:  3   7    5   2   1   4   8   6   9   10  [0—10-2)

3   3遍:  3   5   2    1   4   7   6   8   9   10  [0—10-3)

4   4遍:  3   2   1    4   5   6   7   8   9   10  [0—10-4)

5   5遍:  2   1   3    4   5   6   7   8   9   10  [0—10-5)

6   6  1   2   3    4   5   6   7   8   9   10  [0—10-6)

7   7  1   2   3    4   5   6   7   8   9   10  [0—10-7)

8   8遍:  2   1   3    4   5   6   7   8   9   10  [0—10-8)

9   9  1   2   3    4   5   6   7   8   9   10  [0—10-9)

 

那普通的冒泡排序就是如下这种写法

#include <iostream>

typedef int ElemType;

void BubbleSort(ElemType *arr,int length);

int main() {
    using namespace std;
    std::cout << "BubbleSort!" << std::endl;
    ElemType arr[] = {90,80,70,60,30,20,10};
    int length = sizeof(arr)/ sizeof(arr[0]);
    BubbleSort(arr,length);
    for (int i = 0; i < length; ++i) {
        cout<<"The "<<i+1<<"th element is "<<arr[i]<<endl;
    }
    return 0;
}

void BubbleSort(ElemType *arr,int length){
    ElemType temp;
    for (int i = 1; i < length ; ++i) {//进行n-1趟排序
        for (int j = 0; j < length-i; ++j) {//在前n-i个未完成的排序中进行比较和元素移动
            if(arr[j] > arr[j+1]){//交换
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

时间复杂度:最好情况若表中的元素已经符合正向排序,那么只需比较n-1次即可排序完成,但是程序并不知道这已经完成了,于是会继续执行,那么执行次数为n-1+n(n-1)/2+交换次数,最好情况交换次数为0,最坏为3*n(n-1)/2,最终拟合时间复杂度为O(n^2)

 

那么对于已经基本有序的表能否更快一点呢?意思是让系统知道这个表已经排完序的时候,不用每次都执行完浪费时间呢?

我想唯一能让计算机知道这一点的就是用计算机的语言去告知他,就是设置标志位。

我的构想是,若在交换的内外设置标志位,标志不同的状态,每次只要进入了if语句,改变了元素,证明这次就没有排序完成;若没有进入if语句,那么就意味着其实已经完成排序可以不用继续进行下去了。

代码如下:

#include <iostream>
#include <curses.h>

typedef int ElemType;

void BubbleSort(ElemType *arr,int length);

int main() {
    using namespace std;
    std::cout << "BubbleSort!" << std::endl;
    ElemType arr[] = {90,80,70,60,30,20,10};
    int length = sizeof(arr)/ sizeof(arr[0]);
    BubbleSort(arr,length);
    for (int i = 0; i < length; ++i) {
        cout<<"The "<<i+1<<"th element is "<<arr[i]<<endl;
    }
    return 0;
}

void BubbleSort(ElemType *arr,int length){
    ElemType temp;
    bool CHANGE = true;//初始化为true
    for (int i = 1; i < length && CHANGE ; ++i) {//进行n-1趟排序,判断条件为true
        CHANGE = FALSE;//外部判断先为false
        for (int j = 0; j < length-i; ++j) {//在前n-i个未完成的排序中进行比较和元素移动
            if(arr[j] > arr[j+1]){//交换
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                CHANGE = true;//如果还有元素进行交换,那么就置为true
            }
        }
    }
}

 

对于最坏的情况,冒泡排序当然无力改变时间复杂度,但对于最好的情况或是已经基本有序的数列,可以有效缩短时间。拿最好情况来比较,假设数列已经简单有序,则只需比较n-1次就结束函数了,无需再进行后面的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值