1.冒泡排序:从头开始依次比较相邻的元素,我们定义为cur和next,如果cur>next,则交换cur和next所指向的元素(假设我们想将n个数从小到大进行排序)。从最开始的一对到最后一对,经过一趟比较便可以找出所有元素中最大的数,此时最大的数就是最后一个元素。然后重复上述步骤,最多经过n-1趟的比较便可以完成排序。如图:
2.接下来,我们对冒泡排序进行算法分析
时间复杂度:最好情况:所有元素初始状态为有序,则不需要排序,时间复杂度为O(n);
一般情况:如我刚才所举的例子,一部分有序,时间复杂度大于O(n)小于O(n^2);
最坏情况:完全逆序,例如:想要从小到大排序(从大到小进行排序),但初始序列为从大到小(从小到大);时间复杂 度为O(n^2);
空间复杂度:在每一趟的比较中没有任何的额外开销,所以空间复杂度为O(1);
稳定性:冒泡排序就是把小的元素或者大的元素往后调,比较和交换都发生在相邻的元素之间。如果两个元素相等显然是不需要进行交换的,所以相同元素的前后顺序并没有改变,所以冒泡排序是稳定排序。
如图:两个7排序后的前后顺序未发生改变。
![](https://i-blog.csdnimg.cn/blog_migrate/9fdca71a9e18236f4be4dc2050807b4e.png)
3.源代码
void PrintSort(int arr[],size_t size)
{
size_t i=0;
for(; i<size; ++i)
{
printf(" %d ",arr[i]);
}
printf("\n");
}
void Swap(int *x,int *y)
{
*x^=*y;
*y^=*x;
*x^=*y;
}
void BubbleSort(int arr[],size_t size)
{
size_t i=0;
size_t j=0;
for(; i<size; ++i)
{
j=0;
for(; j<size-1-i; ++j)
{
if(arr[j]>arr[j+1])
{
Swap(&arr[j],&arr[j+1]);
}
}
}
}
int main()
{
int arr[]={12,32,43,5,5,46,576,7};
size_t size=sizeof(arr)/sizeof(arr[0]);
BubbleSort(arr,size);
PrintSort(arr,size);
system("pause");
return 0;
}
运行结果:
这个程序还不够好,试想一下,可不可以改进一下呢?如果我们的序列已经有序,它是不是还要去进行一次次的比较呢?那么此时我们便可以定义一个FLAg,初始情况下FLAG=0;进一次比较循环,我们就将它置为1,如果在第一次循环之后FLAG还是0,那么说明我们的序列本身已经有序,就不需要再继续比较了,直接break。这种做法可以在一定程度上提高执行效率。
优化后的冒泡排序:
void BubbleSort(int arr[],size_t size)
{
size_t i=0;
size_t j=0;
int FLAG=0;
for(; i<size; ++i)
{
j=0;
for(; j<size-1-i; ++j)
{
if(arr[j]>arr[j+1])
{
FLAG=1;
Swap(&arr[j],&arr[j+1]);
}
}
if(FLAG==0)
{
break;
}
}
}