详解冒泡排序和对其优化的Shaker 排序

58 篇文章 0 订阅
30 篇文章 1 订阅

顾名思义,就是排序时,最大的元素会如同气泡一样移至右端,其利用比较相邻元素的方法,将大的元素交换至右端,所以大的元素会不断的往右移动,直到适当的位置为止。

基本的气泡排序法可以利用旗标的方式稍微减少一些比较的时间,当寻访完阵列后都没有发生任何的交换动作,表示排序已经完成,而无需再进行之后的回圈比较与交换动作,例如:

排序前:95 27 90 49 80 58 6 9 18 50

27 90 49 80 58 6 9 18 50 [95] 95浮出 

27 49 80 58 6 9 18 50 [90 95] 90浮出 

27 49 58 6 9 18 50 [80 90 95] 80浮出 

27 49 6 9 18 50 [58 80 90 95] ...... 

27 6 9 18 49 [50 58 80 90 95] ...... 

6 9 18 27 [49 50 58 80 90 95] ...... 

6 9 18 [27 49 50 58 80 90 95] 由于接下来不会再发生交换动作,排序提早结束 

在上面的例子当中,还加入了一个观念,就是当进行至ii+1时没有交换的动作,表示接下来的i+2n已经排序完毕,这也增进了气泡排序的效率。 


void Bubble(int number[])
{
     int i, j, flag = 1;
     for(i = 0; i < MAX && flag; i++)
     {
           /*设置一个哨兵,如果后面是有序的 那么就没有做交换的必要了 */
           flag = 0; 
           for(j = 0; j < MAX-1; j++)
           {
                 if(number[j] > number[j+1])
                 {
                     SWAP(number[j], number[j+1]);      
                     flag = 1;
                 }
           }      
     } 
     printf("Sorted   array is : ");
     for(i = 0; i < MAX; i++)
          printf("%d ", number[i]);      
     printf("\n");
         
}

上述的冒泡排序已经不是纯粹意义上的冒泡排序了,加入了旗标和减少了比较的范围。其算法复杂度很容易得知是O(n*n),从冒泡的特征可以看出每次都是将最大值冒到右边,那么我们也可以把最小值冒到左边,同理,也可以两者同时进行,那么两者同时进行的排序就是shake 排序,

一个排序的例子如下所示:

排序前:45 19 77 81 13 28 18 19 77 11

往右排序:19 45 77 13 28 18 19 77 11 [81]

向左排序:[11] 19 45 77 13 28 18 19 77 [81]

往右排序:[11] 19 45 13 28 18 19 [77 77 81]

向左排序:[11 13] 19 45 18 28 19 [77 77 81]

往右排序:[11 13] 19 18 28 19 [45 77 77 81]

向左排序:[11 13 18] 19 19 28 [45 77 77 81]

往右排序:[11 13 18] 19 19 [28 45 77 77 81]

向左排序:[11 13 18 19 19] [28 45 77 77 81]


我们可以用两个旗标来记录左边已经排好序的位置和右边已经好的位置, 需要注意的地方是每次将队列向左边冒一次,那么就是将最小值冒到了左边,反之就是将最大值冒到了右边。


void UltimateBubbleSort(int number[])
{
     int left = 0, right = MAX-1, offset, i;
     // offset 表示偏移量 
     while(left < right)
     {
          // 向左边冒泡 是将最小值冒到左边 
          for(i = right; i > left; i--)
          {
                if(number[i] < number[i-1])
                {
                    SWAP(number[i], number[i-1]);               
                    offset = i;
                }
          }  
          left = offset;
          
          // 向右边冒泡 是将最大值冒到左边 
          for(i = left; i < right; i++)
          {
                if(number[i] > number[i+1])
                {
                    SWAP(number[i], number[i+1]);
                    offset = i;             
                }      
          }
          right = offset;
     }
     
      printf("Sorted   array is : ");
     for(i = 0; i < MAX; i++)
          printf("%d ", number[i]);      
     printf("\n");
}

整体的代码如下:


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t = x; x = y; y = t;}

void Bubble(int number[])
{
     int i, j, flag = 1;
     for(i = 0; i < MAX && flag; i++)
     {
           /*设置一个哨兵,如果后面是有序的 那么就没有做交换的必要了 */
           flag = 0; 
           for(j = 0; j < MAX-1; j++)
           {
                 if(number[j] > number[j+1])
                 {
                     SWAP(number[j], number[j+1]);      
                     flag = 1;
                 }
           }      
     } 
     printf("Sorted   array is : ");
     for(i = 0; i < MAX; i++)
          printf("%d ", number[i]);      
     printf("\n");
         
}

void UltimateBubbleSort(int number[])
{
     int left = 0, right = MAX-1, offset, i;
     // offset 表示偏移量 
     while(left < right)
     {
          // 向左边冒泡 是将最小值冒到左边 
          for(i = right; i > left; i--)
          {
                if(number[i] < number[i-1])
                {
                    SWAP(number[i], number[i-1]);               
                    offset = i;
                }
          }  
          left = offset;
          
          // 向右边冒泡 是将最大值冒到左边 
          for(i = left; i < right; i++)
          {
                if(number[i] > number[i+1])
                {
                    SWAP(number[i], number[i+1]);
                    offset = i;             
                }      
          }
          right = offset;
     }
     
      printf("Sorted   array is : ");
     for(i = 0; i < MAX; i++)
          printf("%d ", number[i]);      
     printf("\n");
}

int main()
{
    int number[MAX], i;
    
    srand(time(NULL));
    
    printf("Original array is : ");
    for(i = 0; i < MAX; i++)
    {
          number[i] = rand() % 100;
          printf("%d ", number[i]);      
    }
    printf("\n");
    
 //   Bubble(number);
      UltimateBubbleSort(number);
    
    system("pause");
    return 0;    
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值