排序(一) 冒泡排序

思路
两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

冒泡排序初级版

/* 对顺序表 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);
		}
		Print(*L);	//test
	}
}
举例说明上述算法。
未排序时候  (9,1,5,8,3,7,4,6,2)
i = 1,      (1,9,5,8,3,7,4,6,2)
i = 2,          (1,2,9,8,5,7,4,6,3)
i = 3,          (1,2,3,9,8,7,5,6,4)
i = 4,          (1,2,3,4,9,8,7,6,5)
i = 5,          (1,2,3,4,5,9,8,7,6)
i = 6,          (1,2,3,4,5,6,9,8,7)
i = 7,          (1,2,3,4,5,6,7,9,8)
i = 8,          (1,2,3,4,5,6,7,8,9)
i = 9,          (1,2,3,4,5,6,7,8,9)

冒泡排序

/* 对顺序表 L 做冒泡排序 */
void BubbleSort( SqList *L )
{
	int i, j;
	for(i = 1; i < L->length; i++)
	{
		for(j = L->length - 2; j >= i; j--)
		{
			if(L->r[j] > L->r[j+1])
				swap( L, j, j+1 );
		}
		Print( *L );	//test
	}
}

举例说明上述算法。
未排序时候 (9,1,5,8,3,7,4,6,2)
i = 1,          (1,9, 2,5,8,3,7,4,6)
i = 2,          (1, 2,9, 3,5,8, 4,7,6)
i = 3,          (1,2, 3,9, 4,5,8, 6,7)
i = 4,          (1,2,3, 4,9,5, 6,8,7)
i = 5,          (1,2,3,4, 5,9,6, 7,8)
i = 6,          (1,2,3,4,5, 6,9,7,8)
i = 7,          (1,2,3,4,5,6, 7,9,8)
i = 8,          (1,2,3,4,5,6,7, 8,9)
i = 9,          (1,2,3,4,5,6,7,8, 9)
红色标记是上浮的数字,可见,在每一轮从后向前相邻数据比较,小的数字就会上浮。

优化

试想一下,如果我们待排序的序列式{2,1,3,4,5,6,7,8,9},也就是说,除了第一和第二的关键字需要交换外,别的都已经是正常的顺序。当 i = 1 时,交换了 2 和 1,此时序列已经有序,但是算法仍然不依不饶的将 i= 2 到 9 以及每个循环都执行了一遍, 尽管没有交换数据,但是之后的大量比较还是大大的多余了。
也就是说,我们可以增加一个flag来实现这一算法的改进。
/* 对顺序表 L 做改进冒泡算法 */
void BubbleSort2( SqList *L )
{
	int i, j;
	int flag = TRUE;	/* flag 用来作为标记 */						
	for(i = 1; i < L->length && flag; i++)	
	{	
		/* 若 flag 为 false,则说明没有进入交换的 if 语句中,退出循环 */
		flag = FALSE;	/* 初始为 false */		
		for(j = L->length - 2; j >= i; j--)
		{
			if(L->r[j] > L->r[j+1])
			{
				swap( L, j, j+1 );
				flag = TRUE;	/* 如果有数据交换,则 flag 为 true */
			}
		}
		Print( *L );	//test
	}
}
避免了因已经有序的情况下的无意义循环判断。

复杂度分析


最好情况 n-1 次比较
最坏情况 需要比较 n(n-1)/2 次,并做等数量级的记录移动。
所以,总的时间复杂度为 O(n^2)。


补充
线性表结构:
typedef struct
{
	int r[MAXSIZE+1];	/* 用于存储要排序数组,r[0]用作哨兵或者临时变量 */
	int length;
} SqList;

交换函数
/* 交换 L 中数组r的下标为 i 和 j 的值 */
void swap(SqList *L, int i, int j)
{
	int temp = L->r[i];
	L->r[i] = L->r[j];
	L->r[j] = temp;
}


参考
《大话数据结构》



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值