冒泡算法的简要分析

博主是边学习边写的,看了很多的冒泡算法讲解,觉得不够详细,研究了很久才弄懂,看似简单还是要实现以下才行,记录学习过程。


1.  冒泡排序讲解

实现方法:

1)比较相邻的元素,如果第一个比第二个大,那么交换两个元素

2)对每一对相邻元素做同样的工作, 从第一对到最后一对,这时候最大的数字在最后的位置

3)针对所有元素重复以上步骤,除了最后一个

4)持续每次对越来越少的元素重复上面的步骤,直到没有一对元素需要比较。



文字描述没懂的话,来看看例子~~~

首先原始队列为: 5 9 7 6 1 8 13 4

一共八个数,一般比较7趟就可以按从小到大的顺序排列好

外部循环控制循环趟数(i),内部循环控制比较次数(j)

第0趟: (此时定位i=0;i<=n-1;i++

                   j=1;j<=n-1-i;j++)

1)5 9 7 6 1 8 13 4

                2)  5 7 9 6  1 8 13 4

                3)  5 7 6 9  1 8 13 4

                4)  5 7 6 1 9  8 13 4

                5)  5 7 6 1  8 9 13 4

                6) 5 7 6 1 8  9 13 4

                7)5 7 6 1 8  9 4  13(红色代表已经排好序的)

第1趟:    1) 5 7 6 1 8 9 4 13

               2) 5 6 7 1 8 9 4 13

              3) 5 6 1 7 8 9 4 13

             4) 5 6 1 7 8 9 4 13

             5) 5 6 1 7  8 9 4 13

             6) 5 6 1 7 8  4 9  13

第2趟:1)5 6 1 7 8 4 9 13

              2) 5 1 6 7 8 4 9 13

              3)5 1  6 7 8 3 9 13

              4)5 1 6 7 8 3 9 13

             5) 5 1 6 7 3 8 9 13

           6) 5 1 6 7 3  8 9 13

第3趟:1)1 5 6 7 3 8 9 13

              2) 15 6 7 3 8 9 13

             3)1 5 6 7 3 8 9 13

             4)1 5 6 3 7 8 9 13

第4趟:1) 1 5 6 3 7 8 9 13

            2)1 5 6 3 7 8 9 13

           3) 1 5  3 6 7 8 9 13

  第5趟:1) 1 5  3 6 7 8 9 13

                2)1 3_5  6 7 8 9 13

第6趟: 1)1 3 5 6 7 8 9 13   


代码实现:

  1. void BubbleSort1(int arr[],int len)  
  2. {  
  3.     int i = 0;  
  4.     int j = 0;  
  5.   
  6.     for(i = 0; i < len - 1; i++)  
  7.     {  
  8.         for(j = 0; j < len - i - 1; j++)  
  9.         {  
  10.             int tmp  = 0;  
  11.             if(arr[j] > arr[j+1])  
  12.             {  
  13.                 tmp = arr[j];  
  14.                 arr[j] = arr[j+1];  
  15.                 arr[j+1] = tmp;  
  16.             }  
  17.         }  
  18.     }  
  19. }//没有优化的方法,比较常规; 
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3.   
  4. int main()  
  5. {  
  6.     int arr[] = {6,5,4,3,2,1};  
  7.     int i = 0;  
  8.     int len  = sizeof(arr)/sizeof(arr[0]);  
  9.   
  10.     BubbleSort3(arr,len);  
  11.   
  12.     for(i = 0;i < len; i++)  
  13.         printf("%d ",arr[i]);  
  14.   
  15.     system("pause");  
  16.     return 0;  
  17. }  

优化算法:

1.如果原数组本身就是有一些元素是有序的,那么就不用跑n-1趟来浪费时间,于是我们想到,可以每跑完一趟后判断数组是否有序,一旦有序,则直接return掉;于是可以立一个flag

代码实现:

  1. void BubbleSort2(int arr[],int len)  
  2. {  
  3.     int i = 0;  
  4.     int j = 0;  
  5.   
  6.     for(i = 0; i < len - 1; i++)  
  7.     {  
  8.         int flag = 1;//假定每次进入都是有序的 flag为1;  
  9.         for(j = 0; j < len - i - 1; j++)  
  10.         {  
  11.             int tmp  = 0;  
  12.             if(arr[j] > arr[j+1])  
  13.             {  
  14.                 tmp = arr[j];  
  15.                 arr[j] = arr[j+1];  
  16.                 arr[j+1] = tmp;  
  17.                 flag = 0;//如果发生交换,则flag 置为0;  
  18.             }  
  19.         }  
  20.         if(flag == 1)//如果这趟走完,没有发生交换,则原数组有序;  
  21.             break;  
  22.     }  
  23. }//加入标志位优化;
  24.   
2.在第一种优化的基础上,如果是100个数,仅前面10个无序,后面90个都已经排好序了,而且都大于前面的10个数字,那么在第一趟便利后,发生交换的位置小于10,且这个位置之后的数据肯定有序了,那么记录下这个位置,第二次只要从头遍历到这个位置就可以了。


代码实现:

  1. void BubbleSort3(int arr[],int len)  
  2. {  
  3.     int i = 0;  
  4.     int j = 0;  
  5.     int k = len - 1;//控制内部比较循环  
  6.     int n = 0;  
  7.   
  8.     for(i = 0; i < len -1 ; i++)  
  9.     {  
  10.         int flag  = 1;  
  11.         n = 0;  
  12.         //假定每次进入都是有序的 flag为1;  
  13.         for(j = 0; j < k; j++)  
  14.         {     
  15.             int tmp  = 0;  
  16.             if(arr[j] > arr[j+1])  
  17.             {  
  18.                 tmp = arr[j];  
  19.                 arr[j] = arr[j+1];  
  20.                 arr[j+1] = tmp;  
  21.                 flag = 0;//如果发生交换,则flag 置为0;  
  22.                 n = j;//保存最后一次交换的下标;  
  23.             }  
  24.         }  
  25.           
  26.         if(flag == 1)//如果这趟走完,没有发生交换,则原数组有序;  
  27.             break;  
  28.         k = n;//最后一次交换的位置给k,减少比较的次数;  
  29.     }  
  30. }//最终优化  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值