冒泡排序及优化

先上一段代码

1 for (i=1;i<n;i++)
2   for (j=1;j<=n-i;j++)
3     if (a[j]<a[j+1])
4      {
5           t=a[j];
6           a[j]=a[j+1];
7           a[j+1]=t;
8      } 

这是用冒泡排序对一个无序数组从大到小排序

通过n-1轮比较、交换

每一轮从数组最前面的两个开始比较

相邻两个比较

因为最后排完序是从大到小

所以最后排在前面的数一定比排在后面的数大

所以相邻两个比较的时候如果前面的比后面的小

说明它们的相对位置不符合排序后的最终相对位置

就把它们交换

每一轮交换会把一个最小的数移到最后

n-1轮交换之后就排好序了

比如

93 85 77 68 59 100 43 94 75 82

从大到小排

先比较最前面的两个数,即93 和85

发现93>85符合最终顺序

它们的相对位置没问题

然后继续比较85和77

还是没问题

再比77和68

没问题

比到59和100的时候

就有问题了

因为59比100小

所以就交换这两个数

就变成

93 85 77 68 100 59 43 94 75 82

然后继续比

比到43和94

又有问题

就再交换

变成

93 85 77 68 100 59 94 43 75 82

然后比43和75

交换

变成

93 85 77 68 100 59 94 75 43 82

然后比43和82

再交换

变成

93 85 77 68 100 59 94 75 82 43

这样第一轮就比完了

现在数组里面最后一个数是43

这个数是数组里面最小的

排完序后它的位置一定在最后一个

不会再变了

所以接下来就不用管它

下一轮只要给前n-1个排序

93 85 77 68 100 59 94 75 82 43

以此类推

93 85 77 100 68 59 94 75 82 43

93 85 77 100 68 94 59 75 82 43

93 85 77 100 68 94 75 59 82 43

93 85 77 100 68 94 75 82 59 43

第二轮比完之后第二小的会移到n-1的位置

93 85 77 100 68 94 75 82 59 43

然后最后两个数的位置就不会再变了

第三轮只要给前n-2个数排序

93 85 100 77 68 94 75 82 59 43

93 85 100 77 94 68 75 82 59 43

93 85 100 77 94 75 68 82 59 43

93 85 100 77 94 75 82 68 59 43

93 85 100 77 94 75 82 68 59 43

……

第i轮比完最后会有i个数的位置确定了

所以  for (j=1;j<=n-i;j++)

而外面那个 for (i=1;i<n;i++) 表示比较了n-1轮

这个过程就像每次让最轻的泡泡一点一点升到最上面

所以这个排序算法叫做冒泡排序

n-1轮后,会有n-1个数的位置确定了

那么剩下第n个数的位置也确定了

所以只需比较n-1轮

冒泡排序时间复杂度是O(n2),对于较大的数据会超时

有一个小小的优化感觉时间也没快多少

我们知道经过n-1轮比较、交换后,会得到一个有序数组,但事实上可能只需要i(i<n-1)轮数组就已经有序了,那么i+1→n-1轮的比较就没有必要了,我们可以通过去掉这几轮的比较以减少时间

而对于每一轮的比较,都是比较相邻的两个数,如果某一轮比较没有交换任何两个数,说明此时数组已经有序了,以从大到小排序为例,如果一轮比较后没有交换任何两个数,说明任何两个相邻的数的相对位置都符合排序后的最终相对位置,即,对于任意j(1<=j<=n-i),必满足a[j]>a[j+1](否则就会发生交换),所以此时就可以退出循环了

我们可以设一个标记flag,每一轮开始时将flag赋为false,在这一轮的循环比较中一旦发生交换就把flag赋成true,一轮循环结束后检验flag的值是否为true,若依然为false则说明数组已经有序,可以直接跳出接下来i+1→n-1轮的比较

 

 1 for (i=1;i<n;i++)
 2 {
 3     flag=0;
 4     for (j=1;j<=n-i;j++)
 5     {
 6         if (a[j]<a[j+1])
 7         {
 8             t=a[j];
 9             a[j]=a[j+1];
10             a[j+1]=t;
11             flag=1;
12         }
13     }
14     if (!flag) break;
15 }
原文地址:https://www.cnblogs.com/rabbit1103/p/14018105.html