C:冒泡排序

1e0f36d95fb04c78a598e20fa1049156.jpg

1、冒泡排序介绍:

冒泡排序的核心思想就是:两两相邻的元素进行比较。

先用一个例子来帮助大家理解一下冒泡排序的算法是怎们进行的

有一排高矮不同的人站成一列,要按照从矮到高的顺序重新排队。

冒泡排序的方法就是,从第一个人开始,依次两两比较相邻的两个人的身高。如果左边的人比右边的高,就交换他们的位置。

这样一轮下来,最高的人就像气泡一样“浮”到了最右边。

然后再从头开始,重复刚才的比较和交换,让第二高的人“浮”到右边第二个位置。

就这样一轮一轮地比较和交换,直到所有人都排好序。

2、不使用函数的冒泡排序:

代码展示:

#include <stdio.h>
int main(){int arr[] = { 100,99,3,45,12,55,88,22,13,19 };//随机输入的数字int i = 0;int sz = sizeof arr / sizeof(arr[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 k = arr[j];arr[j] = arr[j + 1];arr[j + 1] = k;}}}	for (i = 0; i < sz; i++){printf("%d ", arr[i]);}//实现排序后的数组打印return 0;}

 结果展示:

b20175b7e8f14278870c90000fb412be.png

2.1 sz的解释:

int sz = sizeof arr / sizeof(arr[0]);

这行代码用于计算数组 arr 中的元素个数。

 sizeof是 C 语言中的一个操作符,用于获取数据类型或者变量所占用的字节数。

 sizeof arr 会返回整个数组所占用的字节数。

 sizeof(arr[0]) 会返回数组中单个元素所占用的字节数。

然后用整个数组占用的字节数除以单个元素占用的字节数,就得到了数组中元素的个数,并将其存储在变量 sz  中。

例如,如果  arr  是一个 int 类型的数组,每个 int 类型通常占用 4 个字节。假设整个数组占用了 40 个字节,那么sz = 40 / 4 = 10 ,即数组中有 10 个元素。

这样做的好处是,即使数组的大小在不同的情况下可能会发生变化,通过这种方式计算元素个数可以提高代码的可维护性和通用性,避免了重复编码数组的大小。

2.2 i  < sz - 1  和 j < sz-1-i 的解释

这里的 i 是进行冒泡排序的总趟数,sz - 1是因为对于一个含有sz个元素的数组,进行 sz - 1 趟冒泡排序就可以完成排序。

这里的 j 是进行一次冒泡排序所要交换的次数, sz-1-i 用于控制每一趟冒泡排序中比较和交换的次数。

以包含 5 个元素的数组为例:

第一趟需要比较 4 次(即 sz-1),因为要把最大的数“浮”到最后位置。

第二趟只需要比较 3 次(即 sz-1-1),因为最大的数已经在最后,不用再参与比较。

第三趟比较 2 次(即 sz-1-2)。

第四趟比较 1 次(即 sz-1-3)。

这样,每一趟比较的次数逐渐减少,通过这种方式可以在经过一定的趟数后完成整个数组的排序。

3、使用函数的冒泡排序:

#include <stdio.h>
void bublle_sort(int arr[], int sz)//实现冒泡排序
{for(int i = 0; i < sz - 1; i++)//总趟数{   //一趟冒泡排序for (int j = 0; j < sz-1-i; j++){if (arr[j] > arr [j + 1] )//相邻两数比较大小{int k = arr[j];arr[j] = arr[ j + 1];arr[j + 1] = k;}}}
}
void printf_arr(int arr[], int sz)//打印排序后的值
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}
int main()
{int arr[] = { 2,3,4,5,6,7,1,8,9,10 };//这里的整数是可以任意输入的,不限数量//写一个函数,实现冒泡排序//假设为升序排列int sz = sizeof arr / sizeof(arr[0]);//求数组中元素的个数bublle_sort(arr, sz);//实现冒泡排序printf_arr(arr, sz);//实现打印排序后的值return 0;
}

这里就比上面那个多了两个函数,里面注释写的还是比较清楚的,可以看一看

4、关于函数冒泡排序的代码改进

void bublle_sort(int arr[], int sz)//实现冒泡排序
{for(int i = 0; i < sz - 1; i++)//总趟数{   //一趟冒泡排序for (int j = 0; j < sz-1-i; j++){if (arr[j] > arr [j + 1] )//相邻两数比较大小{int k = arr[j];arr[j] = arr[ j + 1];arr[j + 1] = k;}}}
}

关于冒泡排序的次数,上述这组代码不管所给的数字是什么顺序排列的,想要改为升序都需要进行45组两数相比,如果所要排序的数组是乱序的话45次还能接受,但是如果所给的顺序是

9 0 1 2 3 4 5 6 7 8

像上述这种顺序改为升序仅仅只需要将9移动到最后一位即可,也就是说只需要一趟冒泡排序即可完成。但是,向上面的代码,当第一趟冒泡排序结束后,会紧接着进行下一趟冒泡排序。虽然排序已经完成,但是后面依旧会继续比较,虽然数字不会再交换顺序。因此,向这种情况我们应该怎么改进呢?

#include <stdio.h>
void bublle_sort(int arr[], int sz)
{
    for(int i = 0; i < sz - 1; i++)//总趟数
    {   //一趟冒泡排序
        int flag = 1;//假设已经有序了
        for (int j = 0; j < sz-1-i; j++)
        {
            if (arr[j] > arr [j + 1] )
            {
                int k = arr[j];
                arr[j] = arr[ j + 1];
                arr[j + 1] = k;
                flag = 0;//说明其中发生了交换,假设不成立
            }
        }
        if (flag == 1)//说明假设成立
        {
            break;//跳出循环
        }
    }
}

 看上面被标红的代码,当我们这样优化后,可以减少多余的循环,提高效率。

5、使用指针的冒泡排序:

先补充几个知识点:

数组的数组名arr就是首元素地址,所以我们传参传的其实就是首元素地址bublle_sort(arr, sz);

我们将形参改写为指针,通过指针找回来的还是main函数里的原数组

主函数里的数组传递给冒泡排序函数,冒泡函数里使用的数组依然是主函数里的数组,这是因为数组传参传的是它的地址。

使用指针标识的冒泡函数

#include <stdio.h>                                                               
void bublle_sort(int* arr, int sz)//实现冒泡排序
{for (int i = 0; i < sz - 1; i++)//总趟数{   //一趟冒泡排序int flag = 1;for (int j = 0; j < sz - 1 - i; j++){if (*(arr + j) > *(arr + j + 1))//相邻两数比较大小{int k = *(arr+j);*(arr + j) = *(arr + j + 1);*(arr + j + 1) = k;flag = 0;}}if (flag == 1){break;}}
}
void printf_arr(int* arr, int sz)//打印排序后的值
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", *(arr + i));}printf("\n");
}
int main()
{int arr[] = { 2,3,4,5,6,7,1,8,9,10 };//写一个函数,实现冒泡排序//假设为升序排列int sz = sizeof arr / sizeof(arr[0]);bublle_sort(arr, sz);//实现冒泡排序printf_arr(arr, sz);//实现打印排序后的值return 0;
}

结语:

本篇文章到这里就先结束了,期待大家的的阅读!!!

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394716.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python代码之特征工程基础

1. 什么是特征工程 特征工程是指从原始数据中提取、转换和创建适合于模型训练的数据特征的过程。它是机器学习和深度学习中非常重要的一步&#xff0c;因为好的特征工程可以显著提高模型的性能。特征工程涉及从数据中提取有意义的信息&#xff0c;并将其转换为模型可以理解和使…

Python实战:类

一、圆的面积、周长 class Circle:# 初始化一个类参数&#xff1a;rdef __init__(self,r):self.r r# 计算面积的方法def get_area(self):return 3.14*pow(self.r,2)# 计算周长的方法def get_perimeter(self):return 2*3.14*self.r#创建对象 r eval(input(请输入圆的半径&…

linux系统编程:(4)

1.系统时间的获取函数 1. time函数 功能: 获得1970年到现在的秒数 参数: t:存放秒数的空间首地址 返回值: 成功返回1970年到现在的秒数 失败返回-1 2.localtime 函数 功能: 将一个秒数转化成日历时间 参数: timep:保存秒数空间的地址 返回值: 成功…

深度学习入门(四):激活函数与LSTM

激活函数 激活函数在神经网络中扮演着至关重要的角色。它们的主要功能是引入非线性因素&#xff0c;这使得神经网络能够学习和近似任何非线性函数&#xff0c;从而处理复杂的数据模式和决策边界。如果没有激活函数&#xff0c;即使网络拥有很多层&#xff0c;其表达能力仍然只…

write_sdc和write_script区别

文章目录 一、set_disable_clock_gating_check二、write_sdc和write_script区别1. write_sdc2. write_script 一、set_disable_clock_gating_check set_disable_clock_gating_check对指定的cell/pin/lib_cell/lib_pin设置是否进行clock gating的时序检查。 对于工具插入或者…

多模态大语言模型的免训练视觉提示学习 ControlMLLM

ControlMLLM: Training-Free Visual Prompt Learning for Multimodal Large Language Models github paper 在本研究中&#xff0c;提出了一种无需进行训练的方法&#xff0c;通过可学习的潜变量优化将视觉提示注入到多模态大型语言模型&#xff08;MLLMs&#xff09;中。 在…

本地Linux服务器创建我的世界MC私服并实现与好友异地远程联机游戏

文章目录 前言1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 前言 本…

ttwid、x-bogus、a-bogus、msToken、byted_acrawler等直播参数说明和获取方式

可以参考开源项目&#xff1a;https://github.com/Sjj1024/douyin-live 桌面端的直播间项目&#xff1a;https://github.com/Sjj1024/LiveBox ttwid参数 ttwid类似客户端id&#xff0c;即便是游客模式&#xff0c;也可以对页面数据进行埋点统计&#xff0c;通过收集ttwid下的…

java10-集合框架

1. 集合的简介 1.1什么是集合 集合Collection&#xff0c;也是一个数据容器&#xff0c;类似于数组&#xff0c;但是和数组是不一样的。集合是一个可变的容器&#xff0c;可以随时向集合中添加元素&#xff0c;也可以随时从集合中删除元素。另外&#xff0c;集合还提供了若干个…

Java设计模式(桥接模式)

定义 将抽象部分与它的实现部分解耦&#xff0c;使得两者都能够独立变化。 角色 抽象类&#xff08;Abstraction&#xff09;&#xff1a;定义抽象类&#xff0c;并包含一个对实现化对象的引用。 扩充抽象类&#xff08;RefinedAbstraction&#xff09;&#xff1a;是抽象化角…

搭建基于树莓派的Linux学习环境(TODO)

主要是想学一下Linux内核&#xff0c;所以搭一套环境&#xff0c;其实有几个选择&#xff0c;好几个都是我买了板子的。 首先是正点原子的RK3568&#xff0c;最早是想弄安卓&#xff0c;但是SDK的大小真的把我劝退了&#xff0c;动不动几百个G的空间&#xff0c;还有就是保底1…

Mac OS平台,利用 gifify 制作gif教程

一、前言 在很多时候都会用到视频的方式才能直观的表达想表达的东西&#xff0c; 但是视频的文件太大了&#xff0c;所以gif是一个很不错的选择&#xff0c;在网上找了很多免费的都不好用&#xff0c; 最理想的还是直接快捷键唤起&#xff0c;然后选择录制区域&#xff0c;保存…

第128天:内网安全-横向移动IPCATSC 命令Impacket 套件CS 插件全自动

环境部署 案例一&#xff1a; 域横向移动-IPC-命令版-at&schtasks 首先是通过外网web访问到win2008&#xff0c;获得了win2008的权限&#xff0c;这一步不做演示 因为里面的主机都不出网&#xff0c;所以只能利用win2008进行正向或者反向连接 信息收集 域内用户信息&…

【Qt】图形化和纯代码实现Hello world的比较

本篇文章使用俩种方式实现Qt上的Hello world&#xff1a; 通过图形化的方式&#xff0c;在界面上创建出一个控件&#xff0c;显式Hello world通过纯代码的方式&#xff0c;通过编写代码&#xff0c;在界面上创建控件&#xff0c;显示Hello world 图形化方式 双击Forms文件中的…

修改SpringBoot启动图标banner

方式一: 将图标文件命名为banner放在resources目录下 文本文件banner 图片banner 方式二&#xff1a;通过配置文件指定图标路径 指定文本图标&#xff1a;spring.banner.locationclasspath:相对于resources下的位置 ("classpath:"可以省略) 指定图片作为图标: sprin…

同态加密和SEAL库的介绍(一)简介

写在前面&#xff1a; 最近在做同态相关的内容&#xff0c;这里记录下相关的知识点和所踩过的坑&#xff0c;希望对大家有帮助。预计分几篇来详细介绍&#xff0c;从概念简介到不同模式介绍&#xff0c;具体包括了每种模式的编解码和加解密以及他们性能的比对。 虽然同…

win11启动IIS服务配置成web服务器·

为什么要将本地配置为 Web 服务器&#xff1f; 在 Web 开发过程中&#xff0c;将本地配置为 Web 服务器有诸多好处&#xff1a; 实时预览: 修改代码后&#xff0c;无需每次都上传到远程服务器&#xff0c;即可在本地浏览器中实时查看效果。 离线开发: 无需依赖网络连接&#x…

R9000P 双系统安装 win11 和 ubuntu

网上了解到一堆关于 r9000p 安装较老的ubuntu系统&#xff0c;会有一堆问题 可能是电脑硬件比较新&#xff0c;较老的系统相关方面不兼容 那么干脆直接装新一点的系统 我安装了 Ubuntu 22.04 1 根据相关教程利用u盘制作系统盘 ultraISO 推荐使用清华源 速度快一点 https://…

AI资本泡沫要来了么?——Coatue EMW 2024会议摘要

引言 随着生成式人工智能的快速发展&#xff0c;科技领域正经历着一场前所未有的变革。然而&#xff0c;伴随这一热潮而来的&#xff0c;是关于AI资本泡沫的激烈讨论。历史上&#xff0c;每一次技术革命都带来了巨大机遇&#xff0c;同时也伴随着泡沫和风险。本文将通过Coatue…

企业级敏捷框架:业务驱动型敏捷与产品需求团队

本文介绍了一种新的企业级敏捷框架——业务驱动型敏捷&#xff08;Business-driven Agile&#xff09;与 PRT&#xff08;Product Requirement Team&#xff09;&#xff0c;旨在解决传统敏捷方法中需求定义的瓶颈&#xff0c;从而提升产品价值并提高开发效率。原文: A new ent…