冒泡排序和他的优化

冒泡排序是常常使用的排序,面试中也常常用到。

他的特点是:

1.简单 

冒泡排序的逻辑是相邻元素进行比较和交换,经过一轮排序至少可以确定一个有序的元素。

那么可以得出结论:排序n个元素,需要n-1轮排序。

for (x =0 ;x <len-1 ;++x)

经过一轮排序,可以把最大或者最小的元素移动到数组的一边,下一轮在排序时,减少排序元素的数目。

for (y = len-1; y > x; --y)

比较a[y]-1 和a[y]的大小,来决定排序的方式

if (a[y-1] > a[y])

swap(&a[y-1],&a[y]);

2.稳定性

排序稳定的意思是说排序前后,key相同的元素的的相对位置不变。那么这个有什么用呢?

有些算法的前提就是稳定的排序,所以这根具体的算法有关系。

比如:对字符串从小到大排序,ast     aqt

排序按照第1,2,3 。。。进行比较

第二次比较的是是ast 在aqt前面,按照第三个字符比较时,排序不稳定,ast可能跑到aqt的后面,这样排序就造成了错误。

普通的冒泡排序的效率太低了,时间复杂度是O(n2),下面是提高冒泡排序的一些方法。


1.设置标志位,记录在一轮排序中是否有过元素交换

比如  5个元素   1  2  3  4  5,显然这已经是有序的数组。但是算法不知道啦,算法不能看到这个数组已经是有序的。

        所以需要给他安上一双“眼睛”,去监视一些情况。正常需要5个元素,需要4轮循环。

但是只要有交换情况,就给改变标志位,在一轮循环之后去检查这个标志位,那么在第一轮循环结束后,我就结束排序的过程了。

int i,j,flag;

for (i = 0;i <len-1;++i)

{

flag = 0;//需要在一轮循环开始时,初始化为0

for (j =len-1;j>i;--j)

{

if(a[j-1] > a[j])

swap(&a[j-1],&a[j]);

flag = 1;

}

if(flag==0)

break;//退出循环

}

2.上一次交换的位置,比如 经过一轮排序 ,已经形成了这样的序列1 2 3 7 5 。默认的排序是经过一轮排序,确定一个元素。

实际上可能是确定了好几个元素,为了减少交换的次数,需要从上次交换的元素的位置开始排序,而不是默认的一次增加一个的排序。


int i,j,flag,swap=0;

for (i = 0;i <len-1;i = swap)//取消默认的+1,减少排序次数。

{

flag = 0;

for (j =len-1;j>i;--j)

{

if(a[j-1] > a[j])

swap(&a[j-1],&a[j]);

flag = 1;

swap = j;//获得一轮循环的交换的下标。

}

if(flag==0)

break;//退出循环

}


总结:经过测试,冒泡排序经过优化之后的效率和没有优化的冒泡排序差不多。所以,冒泡排序本身效率就不高,就不要想着提高什么效率了,

真的需要提高效率就选择别的排序方法。

最后说一下冒泡的记忆口诀:

外加加 内减减

内大于外

比较外-1 和外

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值