算法-排序-冒泡排序

原理

  所谓冒泡排序法,就是对一组数字进行从大到小或者从小到大排序的一种算法(因为越大或越小的元素会经由交换慢慢“浮”到数列的顶端,故名)。具体方法是,从第一个数值开始,如果相邻两个数的排列顺序与我们的期望不同,则将两个数的位置进行交换;如果其与我们的期望一致,则不用交换。一般地,如果有N个数需要排序,则需要进行(N-1)趟起泡,改进版的冒泡排序需要排序的次数可能会有所减少。
  下面这个算法是我们很容易想到的:

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

  根据上面排序的算法,我们以{1,3,6,5,8,4}为例进行分析。首先这样的算法对六个数来说需要排5趟,每一趟的结果如下:
  第一趟:{1,3,5,6,4,8}
  第二趟:{1,3,5,4,6,8}
  第三趟:{1,3,4,5,6,8}
  第四趟:{1,3,4,5,6,8}
  第五趟:{1,3,4,5,6,8}
  像上面这种情况,其实我们只用了三趟数据就已经有序了,那怎样改进才能不用每次都要排(N-1)趟呢?
  其实我们可以在每次发生数据交换的地方做一个标记,如果发生了数据交换,我们就继续排下去,如果没有发生数据交换,那就说明数据已经是有序的了,此时我们就可以不用再排下去了。从而使排序更高效一些。我们可以使用下面的改进版本的冒牌排序:

void bubble_sort2(int a[], int n) {
    int i, j, flag;
    for (i = n - 1; i > 0; i--) {
        flag = 0;
        for (j = 0; j < i; j++) {
            if (a[j] > a[j + 1]) {
                swap(a[j], a[j + 1]);
                flag = 1;
            }
        }
        if (flag==0) {
            //若没有发生交换,说明数据已经有序
            break;
        }
    }

}

冒泡排序的时间复杂度

  冒泡排序的时间复杂度是O(N2)
  假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1次!因此,冒泡排序的时间复杂度是O(N2)。

冒泡排序的稳定性

  冒泡排序是稳定的算法,它满足稳定算法的定义。
  算法稳定性 – 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。所以这个排序算法是稳定的!

一个完整的示例

#include<stdio.h>
//求数组的长度
#define LEN(array) (sizeof(array))/(sizeof(array[0]))
//交换两个数
#define swap(a,b) (a^=b,b^=a,a^=b)

// 使用时要传址
//void swap(int* x, int* y) {
//  int tep = *x;
//  *x = *y;
//  *y = tep;
//}


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

void bubble_sort2(int a[], int n) {
    int i, j, flag;
    for (i = n - 1; i > 0; i--) {
        flag = 0;
        for (j = 0; j < i; j++) {
            if (a[j] > a[j + 1]) {
                swap(a[j], a[j + 1]);
                flag = 1;
            }
        }
        if (flag==0) {
            //若没有发生交换,说明数据已经有序
            break;
        }
    }

}

void main() {
    int i;
    int a[] = { 1,3,2,8,5,7};
    int len = LEN(a);
    printf("Before sort:");
    for (i = 0; i < len; i++) {
        printf("%d\t", a[i]);
    }
    printf("\n");
    bubble_sort1(a, len);
    //bubble_sort2(a, len);
    printf("After sort:");
    for (i = 0; i < len; i++) {
        printf("%d\t", a[i]);
    }
    printf("\n");
}

   运行结果如下:
   冒泡排序运行结果

参考http://www.cnblogs.com/skywang12345/p/3596232.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值