目录
一、冒泡排序的概念
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
这里我根据网课内容总结了一点:冒泡排序的核心思想就是两两相邻的元素进行比较
二、冒泡排序的实现
请各位C友先看冒泡排序的代码实现:
#include <stdio.h>
void bubble_sort(int arr[],int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
//此为一趟冒泡排序,而一趟冒泡排序仅能把最大的数排序到数组的最末尾处,因此还需要 sz-i-1 次冒泡排序,才能把数组中的所有元素排好序
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)
//此为上面提到的 sz-i-1 次冒泡排序,具体为什么是这个值,请看下文分析
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
bubble_sort(arr, sz);
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
这串代码定义了数组 arr[] = { 3,1,7,5,8,9,0,2,4,6 },题目需求是把数组 arr[] 中的元素按从小到大排好序
那么,请看运行截图:
接着,请看实现一趟冒泡排序的思路图:
在此不难看出,一次冒泡排序能把最大数排到数组下标最大的位置,而这次循环了 sz-1 次
而 sz-1-i 次是这样推出来的:
当 sz-1=9 时,此时 sz-1-i 就代表了最大数要循环9次,i 从零逐渐增大,sz-1-i 的值会依次取9 , 8 ,7 , 6 , 5 , 4 , 3 , 2 , 1 ,从而实现9次的循环
三、冒泡排序函数的错误设计
#include <stdio.h>
void bubble_sort(int arr[])
{
int sz = sizeof(arr)/sizeof(arr[0]);
//和正确解法的区别在此,正确的做法会在 main函数把 sz 求出然后传参给 bubble_sort 函数,而这种错误方法则是在 bubble_sort 函数里面求的sz
int i = 0;
for(i=0; i<sz-1; i++)
{
int j = 0;
for(j=0; j<sz-i-1; j++)
{
if(arr[j] > arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
这种写法错误的原因在于:
sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,这里数组名表示整个数组
但当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
也就是说,本来sizeof(arr)是计算整个数组的大小,但由于传参过程只把数组首元素地址传了过去,所以就导致了冒泡排序的错误
所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
那么,函数内部的 sizeof(arr) 结果是4,而不是整个数组的大小,因此, sz = sizof (arr) / sizeof (arr[0])这种写法求出的 sz 也就不是数组元素个数了,自然而然,冒泡排序也就此无法继续进行
四、总结
冒泡排序作为一种高效算法,在蓝桥杯及各种竞赛中也经常出现,是非常有掌握的必要的。在实现冒泡排序的过程中,需要注意以下几点:
●一次冒泡排序能把最大数排到数组下标最大的位置,而这次循环了 sz-1 次
●当 sz-1=9 时,此时 sz-1-i 就代表了最大数要循环9次,i 从零逐渐增大,sz-1-i 的值会依次 取9 , 8 ,7 , 6 , 5 , 4 , 3 , 2 , 1 ,从而实现9次的循环
●当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
●即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
●也就是说,本来sizeof(arr)是计算整个数组的大小,但由于传参过程只把数组首元素地 址传了过去,所以就导致了冒泡排序的错误
以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!