详解冒泡排序

本文介绍了冒泡排序算法,它是计算机科学领域较简单的排序算法,核心思想是两两相邻元素比较。文中给出了C语言实现冒泡排序的代码,分析了冒泡排序函数错误设计的原因,即数组传参时只传首元素地址导致计算数组大小出错,最后强调了掌握该算法的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、冒泡排序的概念

二、冒泡排序的实现

三、冒泡排序函数的错误设计

四、总结


一、冒泡排序的概念

冒泡排序(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)是计算整个数组的大小,但由于传参过程只把数组首元素地      址传了过去,所以就导致了冒泡排序的错误

以上就是本篇博客的全部内容啦,如有不足之处,还请各位指出,期待能和各位一起进步!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲代码的罗根

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值