冒泡排序可以说是最简单的排序方法,同时它也是最原始最慢的排序算法。这种排序方法的基本思想是把待排序的元素看做是气泡,轻的气泡自然要上升,同时重的气泡也要下降。
这个算法要求我们要做的就是进行若干遍(若有n个元素,则需要n - 1次)的自底向上的扫描。每次扫描都检查相邻的两个元素,如果发现轻的气泡排在重的下面则要交换他们的顺序。一遍之后最轻的气泡就会在最高位上了,那么两遍之后次轻的就会出现在第二位。。。。。。知道n - 1次以后,倒数第二轻的出现在n - 1的位置上,最重的自然被排在最后一位。
我们应该可以想到扫描的时候可以有一个小小的优化,也可以说是一个小技巧,就是当我们进行第i次扫描的时候,由于i -1次的扫描已经使前i - 1位排好了顺序,我们没有必要再去扫描了,所以结论就是当进行第i次扫描的时候不需要扫描前i - 1位。
代码:
#define MAX 100000
void BubbleSort( int * P, int total)
... {
int i, j, temp;
for(i = 0; i < total; i++)
for(j = 0; j < total - i - 1; j++)
if(*(P + j) > *(P + j + 1))
...{
temp = *(P + j);
*(P + j) = *(P + j + 1);
*(P + j + 1) = temp;
}
}
int main()
... {
int A[MAX];
int total, i;
printf("Plsase input the number of the array; ");
scanf("%d", &total);
printf("Please input the array: ");
for(i = 0; i < total; i++)
scanf("%d", &A[i]);
BubbleSort(A, total);
for(i = 0; i < total; i++)
printf("%d ", A[i]);
return 0;
}
讨论:
冒泡法在最坏情况下应该是比较了n(n - 1) / 2次的,最好情况下那就是不用比较了,所以平均的比较次数应该是n(n - 1) / 4。这样可以大致的得出算法的时间复杂度是O(n ^ 2)的。
优化一:
冒泡有一个可以改进的方法,就是当BubbleSort函数的内循环如果某一次没有交换元素,则说明该数组已经排序完毕了,此时可以退出返回了。程序中可以用一个标志位来记录内循环中是否进行了元素交换。
代码:
#define MAX 100000
void BubbleSort( int * P, int total)
... {
int i, j, temp, symbol;
for(i = 0; i < total; i++)
...{
symbol = 0; /**//* 观测内循环是否进行过交换的标志 */
for(j = 0; j < total - i - 1; j++)
if(*(P + j) > *(P + j + 1))
...{
temp = *(P + j);
*(P + j) = *(P + j + 1);
*(P + j + 1) = temp;
symbol = 1;
}
if(symbol == 0)
break;
}
}
int main()
... {
int A[MAX];
int total, i;
printf("Plsase input the number of the array; ");
scanf("%d", &total);
printf("Please input the array: ");
for(i = 0; i < total; i++)
scanf("%d", &A[i]);
BubbleSort(A, total);
for(i = 0; i < total; i++)
printf("%d ", A[i]);
return 0;
}
优化二:
优化二就是传说中的双向冒泡法,为什么要说是传说中的双向冒泡呢?因为传说中这个算法可以减少循环的次数,但是仔细看看可以知道,循环次数是减少了,可是比较的次数还是没有少,所以这个算法到底是不是比普通的冒泡法高效呢,以我之见两者是一样的,双向冒泡法只能算是一种比较有意思的算法罢了。
算法的思想就是先正向的扫描并且使一个最大的沉到底,然后反向扫描使一个最轻的升上天,下次扫描不再扫描这两个元素,于是要排序的空间不断的减小,直到只有一个元素的时候排序完毕。
代码:
#define MAX 100000
void bidirectionalBubbleSort( int * P, int total)
... {
int i, first, last, temp;
first = 0;
last = total - 1;
while(first <= last)
...{
for(i = first; i < last; i++) /**//* 正向的部分 */
if(*(P + i) > *(P + i + 1))
...{
temp = *(P + i);
*(P + i) = *(P + i + 1);
*(P + i + 1) = temp;
}
last = i - 1;
for(i = last; i > first; i--) /**//* 反向的部分 */
if(*(P + i) < *(P + i - 1))
...{
temp = *(P + i);
*(P + i) = *(P + i - 1);
*(P + i - 1) = temp;
}
first = i + 1;
}
}
int main()
... {
int A[MAX];
int total, i;
printf("Plsase input the number of the array; ");
scanf("%d", &total);
printf("Please input the array: ");
for(i = 0; i < total; i++)
scanf("%d", &A[i]);
bidirectionalBubbleSort(A, total);
for(i = 0; i < total; i++)
printf("%d ", A[i]);
return 0;
}
有人认为排序的算法在数据结构和算法中是最容易的。有人往往轻视排序算法,只是去研究那些高深的算法和数据结构。可是大家不要忘了,大师Donald E.Knuth用了300多页来写排序算法。也正是篇中所讲的冒泡排序使我在大一的时候理解了for循环和数组的内容。