顾名思义,就是排序时,最大的元素会如同气泡一样移至右端,其利用比较相邻元素的方法,将大的元素交换至右端,所以大的元素会不断的往右移动,直到适当的位置为止。
基本的气泡排序法可以利用旗标的方式稍微减少一些比较的时间,当寻访完阵列后都没有发生任何的交换动作,表示排序已经完成,而无需再进行之后的回圈比较与交换动作,例如:
排序前:95 27 90 49 80 58 6 9 18 50
27 90 49 80 58 6 9 18 50 [95] 95浮出
27 49 80 58 6 9 18 50 [90 95] 90浮出
27 49 58 6 9 18 50 [80 90 95] 80浮出
27 49 6 9 18 50 [58 80 90 95] ......
27 6 9 18 49 [50 58 80 90 95] ......
6 9 18 27 [49 50 58 80 90 95] ......
6 9 18 [27 49 50 58 80 90 95] 由于接下来不会再发生交换动作,排序提早结束
在上面的例子当中,还加入了一个观念,就是当进行至i与i+1时没有交换的动作,表示接下来的i+2至n已经排序完毕,这也增进了气泡排序的效率。
void Bubble(int number[])
{
int i, j, flag = 1;
for(i = 0; i < MAX && flag; i++)
{
/*设置一个哨兵,如果后面是有序的 那么就没有做交换的必要了 */
flag = 0;
for(j = 0; j < MAX-1; j++)
{
if(number[j] > number[j+1])
{
SWAP(number[j], number[j+1]);
flag = 1;
}
}
}
printf("Sorted array is : ");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
}
上述的冒泡排序已经不是纯粹意义上的冒泡排序了,加入了旗标和减少了比较的范围。其算法复杂度很容易得知是O(n*n),从冒泡的特征可以看出每次都是将最大值冒到右边,那么我们也可以把最小值冒到左边,同理,也可以两者同时进行,那么两者同时进行的排序就是shake 排序,
一个排序的例子如下所示:
排序前:45 19 77 81 13 28 18 19 77 11
往右排序:19 45 77 13 28 18 19 77 11 [81]
向左排序:[11] 19 45 77 13 28 18 19 77 [81]
往右排序:[11] 19 45 13 28 18 19 [77 77 81]
向左排序:[11 13] 19 45 18 28 19 [77 77 81]
往右排序:[11 13] 19 18 28 19 [45 77 77 81]
向左排序:[11 13 18] 19 19 28 [45 77 77 81]
往右排序:[11 13 18] 19 19 [28 45 77 77 81]
向左排序:[11 13 18 19 19] [28 45 77 77 81]
我们可以用两个旗标来记录左边已经排好序的位置和右边已经好的位置, 需要注意的地方是每次将队列向左边冒一次,那么就是将最小值冒到了左边,反之就是将最大值冒到了右边。
void UltimateBubbleSort(int number[])
{
int left = 0, right = MAX-1, offset, i;
// offset 表示偏移量
while(left < right)
{
// 向左边冒泡 是将最小值冒到左边
for(i = right; i > left; i--)
{
if(number[i] < number[i-1])
{
SWAP(number[i], number[i-1]);
offset = i;
}
}
left = offset;
// 向右边冒泡 是将最大值冒到左边
for(i = left; i < right; i++)
{
if(number[i] > number[i+1])
{
SWAP(number[i], number[i+1]);
offset = i;
}
}
right = offset;
}
printf("Sorted array is : ");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
}
整体的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t = x; x = y; y = t;}
void Bubble(int number[])
{
int i, j, flag = 1;
for(i = 0; i < MAX && flag; i++)
{
/*设置一个哨兵,如果后面是有序的 那么就没有做交换的必要了 */
flag = 0;
for(j = 0; j < MAX-1; j++)
{
if(number[j] > number[j+1])
{
SWAP(number[j], number[j+1]);
flag = 1;
}
}
}
printf("Sorted array is : ");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
}
void UltimateBubbleSort(int number[])
{
int left = 0, right = MAX-1, offset, i;
// offset 表示偏移量
while(left < right)
{
// 向左边冒泡 是将最小值冒到左边
for(i = right; i > left; i--)
{
if(number[i] < number[i-1])
{
SWAP(number[i], number[i-1]);
offset = i;
}
}
left = offset;
// 向右边冒泡 是将最大值冒到左边
for(i = left; i < right; i++)
{
if(number[i] > number[i+1])
{
SWAP(number[i], number[i+1]);
offset = i;
}
}
right = offset;
}
printf("Sorted array is : ");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
}
int main()
{
int number[MAX], i;
srand(time(NULL));
printf("Original array is : ");
for(i = 0; i < MAX; i++)
{
number[i] = rand() % 100;
printf("%d ", number[i]);
}
printf("\n");
// Bubble(number);
UltimateBubbleSort(number);
system("pause");
return 0;
}