C++桶排序——详解

news/2024/10/1 17:20:12

前言:现在中小学学习C++的人越来越多,可网上搜了搜桶排序的博文,发现大家都写得好深奥,于是,便有了这篇简单易懂(不是)的桶排序文章

 

思考一下,你面前有一些不大的数字,但是它们是乱序的,请问你如何将它们排成有序的序列?

 不妨,让我们把这些数字当成生活中常见的东西,比如,这些都是不同种类的垃圾编号,我们要将这些垃圾进行分类摆放整齐,那自然的,我们需要有一些垃圾桶

可以发现,这些垃圾的编号种类不是很多,最小是1,最大是7,那么我们最多只需要准备7个垃圾桶就可以了,编号为1到7

 

接下来,就是把每个垃圾丢到对应的垃圾桶中就可以了,然后每一个垃圾桶,就统计有多少个垃圾被丢到了这里面

 

 

 

 

 

 

 

 

 

 

 以上就是将垃圾丢进垃圾桶的过程了,让我们回到编程中来分析一下这个过程中,我们得到了哪些数据

首先,很明显垃圾丢进垃圾桶的过程,是从左到右将垃圾依次丢入的,这符合循环的重复执行概念,所以这个过程是在循环里实现的

然后,对于循环里每一个垃圾的数值,我们设定为x; 

其次,很明显我们有7个连续的垃圾桶排放在一期,这符合数组的定义,所以我们将这7个垃圾桶定义为数组,int vis[8],下标从1到7

思考垃圾丢进垃圾桶之前,桶应该都为空,所以vis数组应该初始化为0,表示初始时任何一个垃圾桶都没有垃圾

思考垃圾丢进垃圾桶过程中,桶里面的数字会 + 1,表示这个垃圾桶多了一个垃圾,用代码表示可以写成 vis[x] = vis[x] + 1;意为x号垃圾桶的垃圾数量加1

int main()
{int vis[8] = {},x,n;//vis[i]:i出现的次数 cin >> n;for(int i = 1; i <= n; i++){cin >> x;vis[x]++; //x出现的次数 + 1 
    }return 0;
}

 

现在,让我们考虑一下按垃圾桶的顺序,依次将桶里面的垃圾全部取出,看看能不能实现排序的效果

①:vis[1] = 2,说明1号垃圾有两个,我们要取出两个1

 ②:vis[2] = 2,说明2号垃圾有两个,我们要取出两个2

③:vis[3] = 0,说明3号垃圾没出现,那就不必理会

④:vis[4] = 2,说明4号垃圾桶有两个垃圾,那就要取出两次4

 ⑤:vis[5] = 1,说明5号垃圾桶有一个垃圾,那就要取出一次5

 

⑥:vis[6] = 0,说明6号垃圾没出现,那就不必理会

⑦:vis[7] = 1,说明7号垃圾桶有一个垃圾,那就要取出一次7

 

最后,来看一下程序取出桶里数字的过程

for(int i = 1; i <= 8; i++)
{while(vis[i] >= 1){cout << i << " ";vis[i]--; //取出i,减少i出现的次数 
    }
}

输入:

8

1 4 1 5 2 5 2 7

输出:

1 1 2 2 4 5 5 7

完整代码:

#include<bits/stdc++.h>
using namespace std;int main()
{int vis[8] = {},x,n;//vis[i]:i出现的次数 cin >> n;for(int i = 1; i <= n; i++){cin >> x;vis[x]++; //x出现的次数 + 1 
    }for(int i = 1; i <= 7; i++) //桶的编号是1到7{while(vis[i] >= 1){cout << i << " ";vis[i]--; //取出i,减少i出现的次数 
        }}return 0;
}

 

 

细节问题:

1.可以发现在桶存储数据的过程中出现了空桶,说明会有空间浪费的情况出现,如果在n个数据中,有数据x出现大小超过1e7(1千万),就意味着我们要准备超过1e7个桶,这样会严重浪费系统内存,因此,桶排序只适合出现的数据都被限制在比较小的范围内的时候使用,例如最大不超过1e5或1e6

2.桶排序的时间复杂度,可以发现我们只需要一次循环n个数,就可以将每个数丢到桶里,说明这个算法只需要一重循环可以实现,对于一重循环n个数的程序,我们称其时间复杂度为O(n),但是别忘了,桶的数量不一定是n个,设桶的数量为k个,那么在取出桶的过程中也是一个1到k的循环,为O(k),所以整体的时间复杂度为O(n + k),还是比较快速的

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

2024.5.31

8-3 【Python0027】函数图形绘制分数 10全屏浏览作者 doublebest单位 石家庄铁道大学【题目描述】设,,,其中,完成下列操作:(1)在同一坐标系下用不同的颜色和线型绘制y1、y2和y3三条曲线;(2)在同一绘图框内以子图形式绘制y1、y2和y3三条曲线。 【练习要求】请给出源代…

单连接多路径,合并多服务器公网带宽---MPTCP---aggligator

https://sliphua.work/try-mptcp/#%E5%BC%80%E5%8F%91%E8%80%85%E6%8E%A5%E5%85%A5对单一连接进行拆分发送合并接收,有拓展传输层 TCP 的 MPTCP 标准,也有使用普通 TCP 自定义应用层协议来实现的纯上层工具。理论上来说,前者的上限更高,后者兼容度更广。 这几天分别尝试了一…

6.15 工程数学实验一

实验一:黄金分割法(0.618法)程序设计 一、实验目的通过一维寻优黄金分割法的程序设计,培养学生计算机的应用能力,并为今后无约束优化方法的学习和编程,奠定基础;掌握缩小寻优区间的黄金分割法。二、实验内容(1)请用0.618法求解优化问题:的极小点和极小值(进退法确定…

如何快速开发一个鸿蒙原生app

小程序转鸿蒙原生app的创新开发方式,为开发者提供了快速、便捷的开发途径,助力开发者高效地将小程序业务迁移至鸿蒙生态,同时也为用户提供了更加丰富、流畅的应用体验。展望未来,随着技术的不断发展和完善,相信将会有更多创新的开发模式涌现,为开发者和用户带来更加便利、…

远程服务器不能复制粘贴解决方法

主要有两种情况: 1、复制粘贴功能原本可以用,突然失灵了 2、从头到尾都无法使用这个复制粘贴功能针对第一种情况,只需重启一下rdpclip.exe就可以了针对第二种情况,步骤: 1、打开任务管理器,查看进程,如果有 rdpclip.exe (有可能是 RDP剪贴板监视程序)进程,先关闭该进…

Lets Encrypt续费证书异常报错解决

Lets Encrypt续费证书异常报错解决 在续费免费证书时出现错误,这里小记一下。 现象#certbot certonly --webroot -w /usr/share/nginx/html -d gh.wqyfchina.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for gh.wqyfchina.comCer…

RevitServer 2018安装教程

1.服务器系统必备环境安装 在“.NET Framework 功能”窗格中,选中“TCP 端口共享”、“HTTP 激活”、“TCP 激活”和“Web 服务器 (IIS) 支持”等复选框。在“Web 服务器角色 (IIS) - 角色服务”窗格上展开“应用程序开发”并选择“ASP”、“CGI”。“在服务器端的包含文件”展…

【Miro】Miro入门(指的是我这篇随笔写得很入门)

Miro入门 参考:Miro API入門 创建APPhttps://miro.com/app/dashboard/ → 右上角头像 →「Settings」→「Your apps」→「Create new app」会提示需要创建Team(如果本来没有加到Team中去应该创建完账号可以自己创建Team)创建Team默认为「Dev team」填写「App Name」,其中「…