在讲排序算法之前,先提供一个顺序表结构。
#define MAXSIZE 10 //用于要排序数组个数最大值,可修改
typedef struct
{
int r[MAXSIZE+1]; //存储要排序数组,r[0]用作哨兵或临时变量
int length; //记录顺序表的长度
}SqList;
定义一个函数swap:
void swap(SqList *L, int i, int j)
{
int temp = L->r[i];
L->r[i] = L->r[j];
L->r[j] = temp;
}
冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。
/* 对顺序表L作交换排序(初级版)*/
void BubbleSort0(SqList *L)
{
int i,j;
for(i=1;i<L->length;i++)
{
for(j=i+1;j<L->length;j++)
{
if(L->r[i]>L->r[j])
{
swap(L,i,j); //交换L->r[i]与L->r[j]的值
}
}
}
}
严格来说上面这一段代码并不是冒泡排序,它不是两两相邻比较,它应该是最简单的交换排序。
下面是正宗的冒泡排序:
/* 对顺序表L作冒泡排序 */
void BubbleSort(SqList *L)
{
int i,j;
for(i=1;i<L->length;i++)
{
for(j=L->length-1;j>=i;j--) //注意j是从后往前循环
{
if(L->r[j]>r[j+1]) //若前者大于后者
{
swap(L,j,j+1); //交换L->r[j]与L->r[j+1]的值
}
}
}
}
冒泡排序优化:
/* 冒泡算法改进 */
void BubbleSort2(SqList *L)
{
int i,j;
Status flag = TRUE; //flag用来作标记
for(i=1;i<L->length && flag;i++) /* 若flag为TRUE则退出循环 */
{
flag = FALSE; //初始为FALSE
for(j=L->length-1;j>=i;j--)
{
if(L->r[j]>L->r[j+1])
{
swap(L,j,j+1);
flag = TRUE; //如果有数据交换,则flag为true
}
}
}
}
代码的改动在于在i变量的for循环中,增加了对flag的判断,若j循环里无数据交换,说明顺序表已经有序,此时flag为false,退出循环。因为代码中包含有两个循环,因此,冒泡排序的时间复杂度为O()。