冒泡排序 深度优化

朴素冒泡

 1 #include<stdio.h>
 2 int main(){
 3     int n[]={0,-1,2,999,317,-5};
 4     int t;
 5     for(int i=0;i<6;i++){
 6         for(int j=0;j<6;j++){
 7             if(n[j]>n[j+1]){
 8                 t=n[j];
 9                 n[j]=n[j+1];
10                 n[j+1]=t;
11             }
12         }
13     }
14     for(int i=0;i<6;i++) printf("%d ",n[i]);
15     return 0;
16 }

通过分析代码,我们会发现,对于每一趟排序

末尾必定是整个序列中最大的数字,他的位置已经固定了。

因此,可以将内层循环做一个优化,

设置一个w变量,使待排序序列的有效长度减少。

 1 #include<stdio.h>
 2 int main(){
 3     int n[]={0,-1,2,999,317,-5};
 4     int t;
 5     int w=6;
 6     for(int i=0;i<6;i++){
 7         for(int j=0;j<w;j++){
 8             if(n[j]>n[j+1]){
 9                 t=n[j];
10                 n[j]=n[j+1];
11                 n[j+1]=t;
12             }
13         }
14         w--;
15     }
16     for(int i=0;i<6;i++) printf("%d ",n[i]);
17     return 0;
18 }

 

这是单侧优化,那么我们很容易就可以想到双侧优化

 1 #include<stdio.h>//Orz,还能优化吗? 
 2 int main(){
 3     int n[10]={0,9,1,-1,-2};
 4 //    for(int i=0;i<10;i++) scanf("%d",&n[i]);
 5     int left=0,right=5;
 6     int t;
 7     while(left<right){//双向排序,当left与right相遇时,说明序列有序。 
 8         for(int i=left;i<right;i++){
 9             if(n[i]>n[i+1]){
10                 t=n[i];
11                 n[i]=n[i+1];
12                 n[i+1]=t;
13             }
14         }
15         right--;//每次从左走一趟,末尾必定为此序列的最大值,下一次不用排序 
16         for(int i=right;i>left;i--){
17             if(n[i]<n[i-1]){
18                 t=n[i];
19                 n[i]=n[i-1];
20                 n[i-1]=t;
21             }
22         }
23         left++;//同理,从右向左走,末尾也一定是最小值,下一次不用排序 
24     }
25     for(int i=0;i<10;i++) printf("%d ",n[i]);
26 }

 

posted @ 2018-10-18 08:28  南风--  阅读(200)  评论(0编辑  收藏  举报