排序5:交换排序(冒泡排序)

来源:互联网 发布:c语言教程视频 编辑:程序博客网 时间:2024/04/29 23:02
       插入排序概括起来,就是把序列分为有序与无序两部分,每趟排序从无序部分选取元素,并通过各种手段在有序部分寻找合适的插入位置,把该元素放进该位置,从而达到排序的目的。而接下来介绍的交换排序,则是通过元素间的比较与交换操作来完成排序的。下面让我们看看最简单也是最经典的交换排序——冒泡排序。
       以序列:49、38、65、97、76、13、27、49为例。第1趟排序时,要处理整个序列。从第1个元素49开始,让它跟第2个元素38对比,49>38,则49与38的位置交换,得:38、49、65、97、76、13、27、49。接着,让现在序列的第2个与第3个元素比较,49<65,则不需要交换它们的位置。然后,让现在序列的第3个与第4个元素比较,65<97,同样不需要交换它们的位置。接下来便是97与76相比,97>76,则两者就要交换位置了,得:38、49、65、76、97、13、27、49。跟着是97>13,同样需要交换两者位置,得:38、49、65、76、13、97、27、49。再继续,将会出现97>27,交换两者位置得:38、49、65、76、13、27、97、49。最后来到97>49,也交换两者位置,得:38、49、65、76、13、27、49、97。至此,第1趟排序结束。大家可发现,序列中最大的元素97被放到序列最尾端,因此,第2趟排序则只处理序列的第1个到第7个元素(初始序列共8个元素)。处理的过程与上述道理完全一致,处理完后,这个处理部分中最大的的元素(也即完整序列的第2大元素)将被放到这7个元素所在部分的最尾端(即整个序列的倒数第2个位置),得:38、49、65、13、27、49、76、97。此后第 i 趟排序只需要处理整个初始序列的第1个到第8-i+1个元素,处理过程与上述一致,每趟处理完,这几个元素中最大的将被放到这几个元素所在部分的最尾端。直到第7趟(即最后一趟,仅剩下头两个元素)也被处理完为止。不过,需要注意的是:比较过程中可能会出现49=49的情况,此时也不应该交换两者位置,以保证稳定排序。最后得到:13、27、38、49、49、65、76、97。
       实际上,对于n个元素的序列而言,冒泡排序最终并不总是需要像如上介绍那样,进行到最多的第n-1趟,只要中途某趟排序过程中没有发生元素交换位置的操作,即可保证整个序列已经有序,不需要再处理下去了。
       由上文的描述可知,冒泡排序是稳定排序,代码如下:
void bubbleSort(int list[],int length){for(int i=length;i>=2;--i)    {        bool flag=false;                for(int j=0;j<i-1;++j)        {        if(list[j]>list[j+1])            {            flag=true;                int temp=list[j];                list[j]=list[j+1];                list[j+1]=temp;            }        }                if(!flag)        break;    }}
       设序列元素个数为n。冒泡排序中,随元素个数变化而改变次数的操作主要是元素的比较与交换操作,且一边比较一边交换,比较次数总不少于交换次数。所以,其时间复杂度的分析只需要看元素比较次数。最好情况下,序列完全顺序,此时仅需进行1趟排序,其要进行n-1次元素的比较;最坏情况时,序列完全逆序,此时需要n-1趟排序,第 i 趟需要比较元素n-i 次,则总比较次数为:1+2+……+n-1。综上所述,冒泡排序的时间复杂度为O(n2)。由于冒泡排序过程中没有使用随元素个数变化而改变数量的辅助存储空间,则空间复杂度为O(1)。
0 0
原创粉丝点击