冒泡排序就是把小的元素往前调或者把大的元素往后调,即小的元素逐渐“冒泡”,较大的元素逐渐“沉底”。其中比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,则不交换;如果两个元素不相等,则需要交换。由于交换是相邻元素,则两个相等元素的前后顺序并没有发生变化,所以冒泡排序是一种稳定排序算法。
首先介绍一种类似于冒泡排序的算法,实际交换为i和j的元素,而不是j和j + 1 的元素,从而导致算法不稳定,即两个相等元素的前后顺序发生变化。
1.算法思路:
设待排序数组为a[n],设置两个标志i和j,i表示当前比较元素,j表示逐个与i元素相比较的下标。假设交换为较小的冒泡,即i次循环结果第i个较小的元素确定。
2.举例说明:
设数组a的元素为:1 8 4 6 9 4(*) 2 (说明:(*)是为了区别两个相等元素
第一趟:i = 0 ;j 从1开始; 因a[i] < a[j],则j++; 其结果为:1 8 4 6 9 4(*) 2
第二趟:i = 1;j 从2开始;a[i] = 8;a[j] = 4;因a[i] > a[j],交换为:a[i] = 4;a[j] = 8;j++;最终为:1 2 8 6 9 4(*) 4 (不稳定)
.......
第六趟:i = 5;结果为:1 2 4(*) 4 6 8 9
程序如下:
void BubbleSort(int a[],int n)
{
int i,j;
for(i = 0;i < n - 1;i++)
{
for(j = i + 1; j < n;j++)
{
if(a[i] > a[j])
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
其次给出一般冒泡排序算法的例子:
第一趟:1 8 4 6 9 4(*) 2 -> 1 4 6 84(*) 2 9
第二趟:1 4 6 8 4(*) 2 9 -> 1 4 64(*) 2 8 9
......
第六趟:1 4 2 4(*) 6 8 9 -> 1 2 4 4(*) 6 8 9
程序如下:
void BubbleSort2(int a[],int n)
{
int i,j;
for(i = 0;i < n - 1;i++)
{
for(j =0; j < n - i - 2;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j]
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
再次对于一些基本有序的可以通过查看是否有交换来终止循环。
程序如下:
void BubbleSort2(int a[],int n)
{
int i,j;
bool flag = true;
for(i = 0;i < n - 1 && flag;i++)
{
flag = false;
for(j =0; j < n - i - 2;j++)
{
if(a[j] > a[j+1])
{
int temp = a[j]
a[j] = a[j+1];
a[j+1] = temp;
flag = true;
}
}
}
}
最后,其实我们可以同时从头和从尾开始比较,每次循环可以确定两个元素的位置,从而提高排序的速度。
程序如下:
void BubbleSort3(int a[],int n)
{
int i,j;
int k = 0;
bool flag = true;
while(flag)
{
flag = false;
for(j = k; j < n - 2 - k;j++)
{
i = n - j - 1;
if(a[j] > a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
flag = true;
}
if(a[i] < a[i-1])
{
int temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
flag = true;
}
}
k++;
}
}
总之,冒泡排序是比较简单易懂的排序算法,是需要基本掌握的。