冒泡排序:
算法思想简单描述:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上
而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较
小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要
求相反时,就将它们互换。
void
BubbleSort(
int
*
A,
int
n)
...
{
for(int i=0;i<n;++i)
...{
for(int j=0;j<n-1;++j)
...{
if(A[j]>A[j+1])
Swap(A[j],A[j+1]);
}
}
}
第一次改进:用一特征位flag表示本次冒泡是否出现交换,如果没有交换则表示到这次冒泡之前已经达到排序要求,故可以退出程序。
void
BubbleSort_flag(
int
*
A,
int
n)
...
{
for(int i=0;i<n;++i)
...{
int flag = 0;
for(int j=0;j<n-1;++j)
...{
if(A[j]>A[j+1])
...{
flag = 1;
Swap(A[j],A[j+1]);
}
}
if(flag == 0)
break;
}
}
第二次改进(以前引用http://blog.youkuaiyun.com/atomic_age/archive/2006/05/02/705507.aspx)
这个算法的时间复杂度为O(n^2)。
而时间复杂度由两部分组成:比较和交换
比较:
最好 平均 最差
O(n^2) O(n^2) O(n^2)
交换
最好 平均 最差
0 O(n^2) O(n^2)
也就是说bubble在最好的情况不需要进行交换,那还要做复杂度为O(n^2)的比较不是太浪费了吗?
下面给出一个bubble sort的改良版本,这个算法在数据基本有序时的时间复杂度为O(n)。最差情况
和bubble函数一样,也是O(n^2)。
这个算法的主要思想是在两个整数最后一次交换后,在前一个整数后面的所有整数都是排序的,因此在
第一层循环的i变化时,无需减1,而只需将i置成这个整数所在的位置。从而第一层循环的次数就不一定是
n - 1,当待排序数组已经是有序时,第一层循环只循环一次。
下面是一种改进的冒泡算法,它记录了每一遍扫描后最后下沉数的
位置k,这样可以减少外层循环扫描的次数。
冒泡排序是稳定的。算法时间复杂度O(n2)
/**/
/*
===============================================
作者:rerli
时间:2003-12-15
目的:重温经典排序思想,并用C语言指针实现排序算法
================================================
*/

void
bubble_sort(
int
*
x,
int
n)
...
{
int j, k, h, t;

for (h=n-1; h>0; h=k) /**//*循环到没有比较范围*/
...{
for (j=0, k=0; j<h; j++) /**//*每次预置k=0,循环扫描后更新k*/
...{
if (*(x+j) > *(x+j+1)) /**//*大的放在后面,小的放到前面*/
...{
t = *(x+j);
*(x+j) = *(x+j+1);
*(x+j+1) = t; /**//*完成交换*/
k = j; /**//*保存最后下沉的位置。这样k后面的都是排序排好了的。*/
}
}
}
}
本文介绍冒泡排序的基本原理及两次优化过程。首次引入标志位减少不必要的循环,二次优化通过记录最后一次交换位置降低内循环次数。改进后的算法在接近有序的数据集上表现更佳。
6154

被折叠的 条评论
为什么被折叠?



