排序_1.冒泡排序

冒泡排序

 冒泡排序(BubbleSort)是一种流行的排序算法,这个排序过程就像一个个向上(向右)冒泡的气泡,最轻的气泡先冒上来(到达R[n]位置),较重的气泡后冒上来,因此形象的称之为冒泡排序.

Bubble_sort

  • 对R[1]~R[n]这n个记录的冒泡排序过程:
    第一趟从第一个记录R[1]开始到第n个记录R[n]为止,对(n- 1个对)相邻的两个记录进行比较,若与排序要求相逆,则交换两者的位置.
    这样,经过一趟的比较,交換後,具有最大关键值的记录就会被交换到R[n]位置.
    第二趟从第一个记录R[1]开始到n - 1个记录R[n-1]为止继续重复上述的比较与交换,这样具有次大关键字的记录就被交换到R[n-1]位置.
    如此重复,在经过n - 1 趟这样的比较与交换之后,R[1]~R[n]这n个记录已按关键字有序.

  • 化简得:

设数组长度为N。
1. 比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。
2. 这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。
3. N=N-1,如果N不为0就重复前面二步,否则排序完成。

冒泡排序视频演示 备份链接1 备份链接2

过程演示:

首先:
       a[0]  a[1]  a[2]  a[3]  a[4]  a[5]  a[6]  a[7]  a[8]  a[9]
     3     0     1     8     7     2     5     4     6     9
第一步:
                                                                        //a[0] 比较 a[1] , 3 <---> 0,大,交换,得:
     0     3     1     8     7     2     5     4     6     9
                                                                        //a[1]   比较 a[2] , 3<--->1,大,交换,得:
     0     1     3     8     7     2     5     4     6     9
                                                                        //a[2]   比较 a[3] , 3<---> 8,小,不变,得:
     0     1     3     8     7     2     5     4     6     9
                                                                        //a[3]   比较 a[4] ,  8<---> 7,大,交换,得:
     0     1     3     7     8     2     5     4     6     9
                                                                        //a[4]   比较 a[5] ,  8<---> 2,大,交换,得:
     0     1     3     7     2     8     5     4     6     9
                                                                        //a[5]   比较 a[6] ,  8<---> 5,大,交换,得:
     0     1     3     7     2     5     8     4     6     9
                                                                        //a[6]   比较 a[7] ,  8<---> 4,大,交换,得:
     0     1     3     7     2     5     4     8     6     9
                                                                        //a[7]   比较 a[8] ,  8<---> 6,大,交换,得:
     0     1     3     7     2     5     4     6     8     9
                                                                        //a[8]   比较 a[9] ,  8<---> 9,小,不变,得:
     0     1     3     7     2     5     4     6     8     9

    这时,经过一次遍历,我们得到了最大值已经被冒(放置)在最右边,接下来,重复这样的操作,到n-1的位置,得到次大.
    
第二次:
       a[0]  a[1]  a[2]  a[3]  a[4]  a[5]  a[6]  a[7]  a[8]  a[9]
     0     1     3     7     2     5     4     6     8     9
                                                                        //a[0] 比较 a[1] , 0 <---> 3,小,不变,得:
     0     1     3     7     2     5     4     6     8     9
                                                                        //a[1] 比较 a[2] , 1 <---> 3,小,不变,得:
     0     1     3     7     2     5     4     6     8     9
                                                                        //a[2] 比较 a[3] , 3 <---> 7,小,不变,得:
     0     1     3     7     2     5     4     6     8     9
                                                                        //a[3] 比较 a[4] , 7 <---> 2,大,交换,得:
     0     1     3     2     7     5     4     6     8     9
                                                                        //a[4] 比较 a[5] , 7 <---> 5,大,交换,得:
     0     1     3     2     5     7     4     6     8     9
                                                                        //a[5] 比较 a[6] , 7 <---> 4,大,交换,得:
     0     1     3     2     5     4     7     6     8     9
                                                                        //a[6] 比较 a[7] , 7 <---> 6,大,交换,得:
     0     1     3     2     5     4     6     7     8     9
                                                                        //a[7] 比较 a[8] , 7 <---> 8,小,不变,得:
     0     1     3     2     5     4     6     7     8     9
  
  ...
    我们可以看到,通过第二次,我们得到了次大元素并放入右边倒数第二个位置上,我们若继续重复,通过得到剩余元素中最大值,可以得到整个元素组里大小排列出来的次序.即可完成排序过程.   

程序代码:

按照此定义,我们很容易写出冒泡排序的程序代码:

void BubbleSort1(int *a, int size)
{
    if(NULL == a || size < 0)
    {
        return;
    }
    int i = 0 ;
    int j = 0 ;
    int n = size;
    for(i = 0; i < n; i++)
    {
        for(j = 1; j < n - i; j++)
        {
            if(a[j-1] > a[j])
            {
                Swap(&a[j-1], &a[j]);
            }
        }
    }
}

即是将元素依次比较,若反序则交换.
我们可以看出,这样的流程会有很多重复.那么我们该怎么样进行优化呢?

如果是一个已经排好序的序列使用上述的方案进行排序的话,则在第一次的循环中则不会出现交换的过程(因为前一个数据的值总是小于后一个数据),所以我们以是否发生了交换作为排序是否结束的标志。及如果一轮排序中并没有发生交换过程则说明当前的序列是已序的。

0 1 2 3 5 8 9 4 6 7 
比如这个序列,基本有序,当我们排好后面的元素后,前面已经排好序,那么我们就可以少进行比较.
我们可以设置一个标志,如果这一趟发生了交换,则为true,否则为false。如果明显如果有一趟没有发生交换,说明排序已经完成。

#define TRUE 1
#define FALSE 0

typedef unsigned char Boolean;

void BubbleSort2(int *a, int size)
{
    if(NULL == a || size < 0)
    {
        return;
    }
    int j = 0 ;
    int n = size;
    Boolean flag = TRUE;
    while(flag)
    {
        flag = FALSE;
        for(j = 1; j < n; j++)
        {
            if(a[j-1] > a[j])
            {
                Swap(&a[j-1], &a[j]);
                flag = TRUE;
            }
        }
        n--;
    }
}

进一步优化,可以一个标记flag来表示当前的状态,在每轮比较的开始把flag置为0,则代表没有发生排序,如果发生了排序,则把flag值为1,在下次的循环中继续进行比较。
如果有100个数的数组,仅前面10个无序,后面90个都已排好序且都大于前面10个数字,那么在第一趟遍历后,最后发生交换的位置必定小于10,且这个位置之后的数据必定已经有序了,记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。

void BubbleSort3(int *a, int size)
{
    if(NULL == a || size < 0)
    {
        return;
    }
    int j = 0 ;
    int n = size;
    int flag = n;
    while(flag > 0)
    {
        n = flag;
        flag = 0;
        for(j = 1; j < n; j++)
        {
            if(a[j-1] > a[j])
            {
                Swap(&a[j-1], &a[j]);
                flag = j;
            }
        }
    }
}

Alog

功能检测

  • 检测代码:
int main()
{
    int i =0;
    int a[] = {3,0,1,8,7,2,5,4,6,9};
    int n = sizeof(a)/sizeof(a[0]);
    BubbleSort1(a, n);
//  BubbleSort2(a, n);
//  BubbleSort3(a, n);
    printf("\n");
    for(i = 0; i < n ; ++i)
    {
        printf("%3d",a[i]);
    }
    printf("\n");
    return 0;
}
  • 运行结果:
root@aemonair:~/Desktop# cc.sh BubbleSort.c 
Compiling ...
-e CC      BubbleSort.c -g -lpthread
-e         Completed .
-e         Sat Jul 23 18:42:01 CST 2016
root@aemonair:~/Desktop# ./BubbleSort 

  0  1  2  3  4  5  6  7  8  9

冒泡排序毕竟是一种效率低下的排序方法,在数据规模很小时,可以采用。数据规模比较大时,最好用其它排序方法。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值