以整数升序排序为例来简单说明一下双向冒泡排序的过程:首先从前往后把最大数移到最后,然后反过来从后往前把最小的一个数移动到数组最前面,这一过程就是第一轮,然后重复这一过程,最终就会把整个数组从小到大排列好。双向冒泡排序要稍微优于传统的冒泡排序,因为双向排序时数组的两头都排序好了,我们只需要处理数组的中间部分即可,而单向即传统的冒泡排序只有尾部的元素是排好序的,这时每轮处理都需要从头一直处理到已经排好序元素的前面一个元素。虽然它在效率上有了点改进,但它也不能大幅度提高其排序的效率,这是由冒泡排序的基本过程所决定了的。在此基础上改进了一下,下面的代码可以实现对奇数偶数分别排序:
#include
"stdafx.h"
#include
<stdio.h>
#include
<stdlib.h>
//一般的冒泡排序
void bubbleSort( int a[], int n)
{
int i,
j, k;
int temp;
for (i
= 0; i < n; i++){ //最多做n-1趟排序
for (j
= 0 ;j < n - i - 1; j++){
if (a[j]
> a[j + 1]){ //把大的值交换到后面
temp
= a[j];
a[j]
= a[j + 1];
a[j
+ 1] = temp;
}
}
printf( "第%d次排序结果:" ,
i + 1);
for (k
= 0; k < n; k++){
printf( "%d\t" ,
a[k]);
}
//printf("\n");
}
printf( "最终排序结果:
" );
for (k
= 0; k < n; k++){
printf( "%d\t" ,
a[k]);
}
}
//改进版的冒泡排序(双向冒泡)
void bidBubbleSort( int a[], int n)
{
int left,
right, t, l, r, j, i = 0;
left
=0;
right
= n -1;
//双向冒泡算法,极大的减少了循环排序的次数
while (left
< right)
{
//必须要给l和r赋值,否则若数组一开始就有序,则right=r中的r未赋值,即报错
l
= left + 1;
r
= right -1;
//第一次循环将最大的值放到末尾
for (j
= left; j < right; j++)
{
if (a[j]
> a[j + 1])
{
t
= a[j];
a[j]
= a[j + 1];
a[j
+ 1] = t;
r
= j;
}
}
right
= r;
//第二次循环将最小的值放到了开头
for (j
= right; j > left; j--)
{
if (a[j]
< a[j - 1])
{
t
= a[j];
a[j]
= a[j - 1];
a[j
- 1] = t;
l
= j;
}
}
left
= l;
printf( "第%d次排序结果:" ,
i + 1);
i++;
for (j
= 0; j < n; j++){
printf( "%d\t" ,
a[j]);
}
}
printf( "最终排序结果:
" );
for (j
= 0; j < n; j++){
printf( "%d\t" ,
a[j]);
}
}
int _tmain( int argc,
_TCHAR* argv[])
{
int score1[]
= {98, 69, 75, 47, 89, 90, 100, 70};
bubbleSort(score1,
8);
printf( "\n" );
int score2[]
= {98, 69, 75, 47, 89, 90, 100, 70};
bidBubbleSort(score2,
8);
system( "pause" );
return 0;
}
|