什么是冒泡排序(为了更清楚地说明局部冒泡)
对于一组无序数据,两两相邻比较,若反序则交换,直到没有反序为止。比如有N个数据,我们需要进行k(0 < k < N )趟冒泡排序,最好的情况是正序,我们只需要进行1趟冒泡排序,最坏的情况是逆序,我们需要进行N-1趟冒泡排序。
什么是局部冒泡
对于N个无序数据,我们在进行一趟冒泡排序时,如果第k个数据和第k+1个数据逆序,那么对第k+1个数据进行一趟向前的冒泡排序,使其移动到合适的位置,也就是说让前面k+1个数据调节为正序。因为这种冒泡法只对前k+1个数据冒泡处理,所以我们称它为——局部冒泡。
/*
摘要:使用局部冒泡法,对无序数据0, 11, 12, 5,6, 13, 8, 9, 14, 7, 10 进行升序排序
完成日期:2012-7-12 23:29
作者:黄路
版本: 1.1
*/
#include <stdio.h>
#define N 11//排序的数据量
void PartBubbleSort(int a[],int n);
void PrintList(int a[], int n);
int main()
{
int a[] = {0, 11, 12, 5,6, 13, 8, 9, 14, 7, 10};
int n = 11;
printf("initial array:\n");
PrintList(a, n);
PartBubbleSort(a, n);
printf("after part bubble sort:\n");
PrintList(a, n);
}
/*
* 功能:排序(递增序列)
* 输入:数据组node a[],数组维数n
*/
void PartBubbleSort(int a[],int n)
{
int temp = 0;
int i = 0;
int j = 0;
for (i = 0; i < n - 1; i++)
{
if (a[i] > a[i + 1])//对a[i + 1]进行一趟向前的冒泡排序
{
j = i + 1;
//将a[i + 1]移动到合适的位置
while(j > 0 && a[j] < a[j - 1])
{
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
j--;
} //end of while
}//end of if
}//end of for
}
/*
功能:输出数组
输入:int list[], int n
输出:无
*/
void PrintList(int list[], int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%4d", list[i]);
}
printf("\n");
}
局部冒泡排序算法至少需进行1 趟扫描, 至多需进行n- 1 趟扫描(其中只有一趟扫描是全局的, 其余趟扫描都是局部扫描, 扫描范围相对小得多。即在待排序数据初始有序( 正序) 情况下, 关键字的比较次数为n- 1, 数据的移动次数为0; 在待排序数据初始逆序的情况下, 关键字的比较次数为n ( n- 1) / 2, 最坏情况下, 每一次比较均会发生数据的交换, 即移动次数为3 n( n- 1) / 2。显然局部冒泡排序与冒泡排序算法具有相同的时间复杂度, 并且在正序和逆序的情况下, 所需的关键字的比较次数和移动次数完全相同。
性能比较
因为渐进的复杂度分析方法不能区分时间复杂度相同的算法,所以我们需要进一步测试。
注:测试所用数据均为随机产生的32 位非负整数,由于测试程序的统计量不是运行时间, 所以表1 中的测试结果不依赖于具体计算机的软、硬件等环境因素, 而仅与算法有关。
由上图可见,局部冒泡法的平局移动次数等于冒泡法,但是局部冒泡法的平局比较次数小于冒泡法。