冒泡排序

基本思想

两两比较相邻记录的关键字,若顺序反了就进行交换,直到所有元素排序正确

将要排序的一组数字进行遍历。
第一次遍历,将相邻的两个数字进行比较,直到这组数字全部比较完成,如果前面比后面的数字大,则进行交换位置,此时可以将最大的数字筛选出来,放到最后的位置上。
第二次遍历,将相邻的两个数字进行比较,直到这组数字全部比较完成,如果前面比后面的数字大,则进行交换位置,将这组数字里面第二大的数字筛选出来,放到倒数第二的位置上。
依次进行遍历,交换位置,直到排序完成。

由于每次遍历都放置好了一个当前最大数,故每次执行遍历的时候的循环次数减一

 

排序所用的结构和函数:

#define MAX 10

//排序所用的顺序表结构 
typedef struct
{
	int a[MAX+1];  //存储排序数组,a[0]用作临时变量,不存入数值  
	int length;    //记录顺序表的长度 
}Sqlist;

//交换 
void swap(Sqlist *L,int i,int j)
{
	int t=L->a[i];
	L->a[i]=L->a[j];
	L->a[j]=t;	
} 

 

 

 

最简冒泡排序:

//初级版冒泡排序
//该算法效率低下,比较当前的关键字时对其余的关键字的排序没有帮助 
void BubbleSort(Sqlist *L)
{
	int i,j;
	for(i=1;i<L->length;i++)
	{
		for(j=i+1;j<=L->length;j++)    //j=i+1 
		{
			if(L->a[i]>L->a[j])
				swap(L,i,j);
		}	
	}	
} 

 

改进的正版冒泡排序:

//交换当前关键字的过程中,其余的关键字也有一定程度的排序
//较小的数字如同气泡一般上浮,故得名冒泡排序 
void BubbleSort(Sqlist *L)
{
	int i,j;
	for(i=1;i<L->length;i++)
	{
		for(j=L->length-1;j>=i;j++)   //逆序循环,注意要有j=i 
		{
			if(L->a[j]>L->a[j+1])	//将前者与后者比较 (注意比较的条件j,j+1) 
				swap(L,j,j+1);
		}	
	}	
} 

 

在待排序的序列大部分都是有序的情况下,传统冒泡排序效率不高,所以我们进行再改进:

//定义一个标志变量 
void BubbleSort2(Sqlist *L)
{
	int i,j;
	int flag=TRUE;
	for(i=1;i<L->length&&flag;i++)     //意为当flag为FALSE时循环退出,此时说明没有发生交换,即有序 
	{
		flag=FALSE;
		for(j=L->length-1;j>=i;j++)
		{
			if(L->a[j]>L->a[j+1])
			{
				swap(L,j,j+1);
				flag=TRUE;		
			}
		}
	}	
} 

有了标志变量之后,有序的部分就不需要一步步去排序了,节省了时间。

 

时间复杂度

最好的情况下,表本身就有序,依据最后改进的代码,进行n-1次比较,无数据交换,时间复杂度O(n)

最坏情况,表为逆序,此时比较:1+2+3+4+...+(n-1)=n*(n-1)/2次,移动次数相同,故O(n^2)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值