冒泡排序基本代码及其优化

冒泡排序是一种交换排序,它的基本思想是:两两比较序列中造句记录的关键字,如果反序则交换,直到没有反序的记录为止。它的运行过程如下(以升序排序为例):

  比如待排序序列数组为:9 2 6 8 7 3 1 0 4 5,将其升序排序成序列0 1 2 3 4 5 6 7 8 9,按照上述冒泡法的运行过程有:

  9 26 8 7 3 1 0 4 5 相邻记录关键字作比较,9>2交换得到序列:2 96 8 7 3 1 0 4 5

  29 68 7 3 1 0 4 5 同样的,9>6,交换后:26 98 7 3 1 0 4 5

  2 69 87 3 1 0 4 5 9>8 交换得到:2 68 97 3 1 0 4 5

  …..

  2 6 8 7 3 1 0 49 5 9>5 交换 得到:2 6 8 7 3 1 0 45 9

  在经过N-1次比较后可以看到关键字最大的元素9经过升序冒泡后已经到了序列的最尾端,这个过程称为第一趟冒泡排序。接着再从序列的第一对相邻元素开始进行第二趟排序:

  2 68 7 3 1 0 4 5 9 ——>2 68 7 3 1 0 4 5 9

  26 87 3 1 0 4 5 9——>26 87 3 1 0 4 5 9

  2 68 73 1 0 4 5 9——>2 67 83 1 0 4 5 9

  ….

  2 6 7 3 1 0 48 59 ——>2 6 7 3 1 0 4 5 8 9

  第二趟排序完成,把关键字8升到了序列倒数第二个位置。可以发现,第二趟排序的比较次数比第一趟少了一次,8与最后的9没有进行比较。

  重复这个过程进行N-1趟的比较之后,,可完成对整个序列的冒泡排序。

  按照这个思路,相应的代码为:

void BubbleSort1(int array[],int arrayLength){int i ,j ;for(i=0;i<arrayLength-1;++i) //进行N-1趟比较 {(array[j]<array[j-1]) //即相邻元素之间的比较Swap(array[j],array[i]); //反序,进行交换 }}

  注意到我在写冒泡排序定义的时候,用红色字体强调了冒泡排序进行比较的是相邻的元素,如下面这段代码,在结构上虽然很像冒泡,实际上只是简单的交换排序:

void Sort(int array[],int arrayLength){int i ,j ;for(i=0;i<arrayLength-1;++i) {for(j=i+1;j<arrayLength;++j)if(array[j]<array[i]) //这里比较的非相邻的元素。该算法不是冒泡Swap(array[j],array[i]);}}

  这种算法做了大量的无用的交换操作,效率是非常低下的。

  排序算法还可以进行优化,设置一个标志域flag,如果某一趟排序发生了变换,那么flag为true。如果某一趟排序没有发生交换,则说明序列已经有序了,不必再进行继续的比较操作,此时flag为false。

{int i ,j ;bool flag = true;for(i=0;i<arrayLength-1&&flag;++i) {flag = false;for(j= 1;j<arrayLength-i;++j)if(array[j]<array[j-1]) {Swap(array[j],array[j-1]);flag = true; //有交换,表明当前序列尚未有序,标志为ture}}}

  冒泡法还有另外一种优化,即只对无序的关键字进行排序。假设有序列array={2,1,5,4,0,6,7,8,9}按升序排序,则只需对无序区{2,1,5,4,0}进行排序即可。使用一个标志来记录无序区的范围:

void BubbleSort3(int array[],int arrayLength){int flag = arrayLength-1;while(flag>0){for(int i = 0;i<arrayLength-1;i++){int k = flag;flag=0;for(int j = 0;j<k;++j)if(array[j]<array[j+1]){Swap(array[j],array[j+1]);flag=j; //记录无序区的末尾位置}}}}

  当然,这种优化情况还是有点特殊的,但序列完全反序时起不到优化作用的。

总体来说,冒泡排序的效率是较为低下在,在数据量小的情况下可以使用,否则应该选择其他的排序算法。

本文章由 造句大全 整理发布

每个人都有自己鲜明的主张和个性,

冒泡排序基本代码及其优化

相关文章:

你感兴趣的文章:

标签云: