新手小白也能看懂的c语言算法——冒泡排序

冒泡排序作为c语言基础入门的算法,也是很多新手的第一个算法,接下来我将以一个例子结合我的理解来讲述,什么是冒泡排序,它是如何使用的。

什么是冒泡排序?

冒泡排序是一种简单的排序算法,它重复地走访要排序的元素列表,一次比较两个相邻的元素,并且如果它们的顺序错误就把它们交换过来。走访列表的工作是重复地进行直到没有再需要交换,也就是说该列表已经排序完成。

冒泡排序的基本思想是:

  1. 从第一个元素开始,依次比较相邻的两个元素,如果顺序不正确(比如按照升序排列,但是前面的元素比后面的大),就交换它们的位置,这样一轮下来,最大的元素就会“冒泡”到最后面。
  2. 对剩余的元素重复以上步骤,每次内循环结束,最大的元素都会被放置到当前未排序部分的最后面。
  3. 重复上述步骤,每次都会将当前未排序部分的最大元素放置到相应位置,直到所有元素都排好序。

尽管冒泡排序的时间复杂度较高,但它的实现非常简单,适用于小规模的数据排序。

题目:

在一个内含多个元素的数组中,将内部元素从小到大的依次排列出来

我对代码进行了详细的注释,大家可以将代码复制到vs编译器里面观看,得到更加的观看效果

//冒泡排序
//两两相邻的元素进行比较
//如果不满足顺序就交换,满足顺序就找下一对
//外层循环表示排的次数
//内层循环表示每次的比较数据
#include <stdio.h>

int main()

{
    // 初始化一个包含 10 个整数的数组
    int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };

    // 使用冒泡排序算法对数组进行排序
    for (int i = 0; i < 9; i++)
    {  
        // 外循环,控制比较轮数,因为每次最大的数都会沉到最后,所以只需要比较 n-1 轮即可
        for (int j = 0; j < 10 - 1 - i; j++)
        {  
            // 内循环,控制每轮比较的次数,每轮比较相邻的两个数
            if (arr[j] > arr[j + 1])
            {  
                // 如果前一个数大于后一个数,就交换它们的位置,使得较大的数往后移动
                int t = arr[j];  
                // 临时变量 t 用于交换两个数的值
                arr[j] = arr[j + 1];  
                // 将后一个数赋值给前一个数
                arr[j + 1] = t;  
                // 将临时变量中存储的前一个数的值赋值给后一个数,完成交换
            }
        }
    }
    // 打印排序后的数组
    for (int i = 0; i < 10; i++)
    {
        printf("%d\t", arr[i]);  // 以制表符分隔的形式打印数组中的每个元素
    }

    return 0;
}


//疑点1
//为什么第一个for循环中,循环次数是9(i<9)


//模拟一下循环过程
//第一轮循环:
//在第一轮循环中,面对10个数,我们需要进行9次比较
//进行之后,最大的数9已经变到最底部了
//第二论循环中,我们就只需要进行8次比较了,因为第一轮的比较已经将最大的数字沉底
//进行之后,现在最大的数字8也就到了底部
//在这个例子中,我们可以看到在每一轮的循环中,最后一个元素都会背确定为当前轮次的最大值
//因此我们可以在下一轮循环时少进行一次比较
//所以我们循环的表达式设置为i<9

//疑点2
//为什么内层循环,循环的上限是 10-1-i
//10是数组的长度,i是外层循环的当前轮次
//具体来说,假设我们有一个长度为10的数组,当前外层循环的轮次是0
//在第一轮循环结束的时候,数组的最后一个元素已经是最大的了,因此不用参加比较
//所以内层循环的上限就是 10-1-0
//当外层循环进行到第二轮的时候,i=1;
//在第二轮循环结束后,数组的倒数第二大的元素已经是次大,因此不需要再次参加比较
//此时内层循环的上限就是 10-1-1
//类推,随着外层循环的进行,每一轮内层循环的上限都会逐渐减小



//疑点3

//如果数组内部的排序,不是9876543210,第一个数字不是最大值,冒泡排序的方法还可行吗?

//在给定的冒泡排序算法中,只要数组中的数字排列符合比较规则,即较大的数字在前,较小的数字在后,那么无论数组中的第一个数字是什么,排序的输出结果都将是按照从大到小的顺序排列。

//冒泡排序的核心思想是比较相邻的两个元素,如果前面的元素大于后面的元素,则交换它们,这样一轮比较下来,最大的元素就会“冒泡”到数组的最前面。因此,即使数组中的第一个数字不是9,只要数组中的数字符合比较规则,经过多次冒泡操作后,最终的输出结果仍然会是按照从大到小的顺序排列的。

//所以,无论数组中的第一个数字是什么,给定的冒泡排序算法都能够得到预期的输出结果。







//写法2


#include<stdio.h>

void bubble_sort(int arr[], int sz)
{
    int i = 0;
    //趟数
    for (i = 0; i < sz - 1; i++)
    {
        //一趟冒泡排序
        int j = 0;
        for (j = 0; j < sz-1-i; j++)
        {
            if (arr[j] < arr[j + 1])
            {
                int tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            }
        }
    }
}

void print_arr(int arr[], int sz)
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d", arr[i]);
    }
    printf("\n");
}
int main()
{
    int arr[] = { 9,8,7,6,5,4,3,2,1,0 };

    int sz = sizeof(arr) / sizeof(arr[0]);
    //元素个数必须在主函数里面求,求好了之后再传给自定义函数。(形参和实参)
    //在c语言中,数组作为参数传递给函数时,实际上传递的是数组的地址,而不是整个数组
    //因此在自定义的函数中获取数组的大小,就无法直接通过参数传递数组来获取数组的大小信息
    //在主函数中计算数组的大小,原因是,主函数是程序的入口,可以直接获取数组的大小,并将其传给所需要的函数
    //自定义的函数中无法直接获取树的大小,因此无法在函数内部计算数组的大小
    //也就是实参传递给形参
    //在函数调用的时候,实参的值会被传递给函数的形参,形成了实参到形参的传递,形参是函数定义时声明的参数
    //形参的值是由函数调用时提供的实参决定的
    //形参无法直接传递给实参(可以通过指针传址),两参之间的传递关系是 : 实参传给形参
    bubble_sort(arr, sz);
    print_arr(arr, sz);
    return 0;
}

在简单的理解冒泡排序之后,不妨来试一试下面的问题

自己输入十个整数,再进行排序

#include<stdio.h>

int main() 
{
    int arr[10];

    printf("请输入十个整数:\n");

    for (int a = 0; a < 10; a++) 
    {
        printf("请输入第 %d 个整数:", a + 1);
        scanf_s("%d", &arr[a]);//不要错写为&arr[10]
    }
    //输入十个整数,存到数组arr中

    for (int i = 0; i < 9; i++)
    {
        for (int j = 0; j < 9 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                int t = arr[j];
                arr[j] = arr[j+1];
                arr[j + 1] = t;
            }
        }
    }
    for (int k = 0; k < 10; k++)
    {
        printf("%d ", arr[k]);
    }

    return 0;
}

上述中使用scanf_s是在vs2022编译器下进行的,也可以通过声明等方式解决。其他编译器,正常使用scanf即可。

感谢您的观看,祝您早日成为编程大牛。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
冒泡排序是一种简单的排序算法,它重复地遍历待排序的元素,比较相邻元素的大小,如果顺序错误就交换它们,直到没有需要交换的元素为止。下面是冒泡排序C语言实现: ```c void bubbleSort(int arr[], int n) { for(int i = 0; i < n-1; i++) { int flag = 0; //是否冒泡 for(int j = 0; j < n-1; j++) { if(arr[j > arr[j+1]) { swap(&arr[j], &arr[j+1]); flag = 1; } } if(flag == 0) { //如果没有发生交换,说明数组已经有序,可以提前结束循环 break; } } } ``` 在这个实现中,冒泡排序函数`bubbleSort`接受一个整型数组`arr`和数组长度`n`作为参数。它使用两层循环来遍历数组,并通过比较相邻元素的大小来进行交换。内层循环每次将最大的元素冒泡到数组的末尾。外层循环控制了冒泡的轮数,每一轮都会将当前未排序的最大元素放在正确的位置上。如果在某一轮的冒泡过程中没有发生交换,说明数组已经有序,可以提前结束循环,从而提高算法的效率。 需要注意的是,上述代码中使用了一个`swap`函数来交换两个元素的值,你可以根据需要自行实现该函数。此外,为了减少冒泡排序的时间复杂度,可以在内层循环中添加一个标志位`flag`,用于标记是否发生了交换。如果某一轮的冒泡过程中没有发生交换,说明数组已经有序,可以提前结束循环。这样可以避免不必要的比较和交换操作,提高排序的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值