排序算法 -计数排序
文章目录
- 1. 计数排序(Counting Sort)
- 1.1 简介
- 1.2 计数排序的步骤
- 1.3 计数排序C语言实现
- 注释说明:
- 1.4 时间复杂度
- 1.5 空间复杂度
1. 计数排序(Counting Sort)
1.1 简介
计数排序(Counting Sort)是一种非比较型整数排序算法,适用于一定范围内的整数排序。它的基本思想是通过计数来确定每个元素在排序后数组中的位置,从而实现排序。计数排序的时间复杂度为 O(n + k),其中 n 是待排序数组的元素个数,k 是待排序元素的取值范围。
1.2 计数排序的步骤
计数排序(Counting Sort)是一种非比较型整数排序算法,适用于一定范围内的整数排序。它的基本思想是通过计数来确定每个元素在排序后数组中的位置,从而实现排序。计数排序的时间复杂度为 O(n + k),其中 n 是待排序数组的元素个数,k 是待排序元素的取值范围。
- 找出待排序数组中的最大值和最小值,以确定元素的取值范围。
- 创建一个计数数组,其大小为最大值与最小值之差加一(因为包含边界值)。
- 遍历待排序数组,统计每个元素出现的次数,并将结果存储在计数数组中。
- 计算前缀和,以确定每个元素在排序后数组中的位置。
- 创建输出数组,根据计数数组中的信息将元素放入正确的位置。
1.3 计数排序C语言实现
#include <stdio.h>
#include <stdlib.h>// 计数排序函数
void CountSort(int* a, int n) {// 初始化最大值和最小值为数组的第一个元素int max = a[0], min = a[0];// 遍历数组,找到最大值和最小值for (int i = 1; i < n; i++) { // 注意这里从1开始,因为第一个元素已经用于初始化if (a[i] > max)max = a[i]; // 更新最大值if (a[i] < min)min = a[i]; // 更新最小值}// 计算计数数组的大小,并动态分配内存int range = max - min + 1;int* count = (int*)malloc(range * sizeof(int));if (count == NULL) {// 内存分配失败处理(这里简单处理为退出程序,实际应用中可能需要更复杂的错误处理)fprintf(stderr, "Memory allocation failed\n");exit(EXIT_FAILURE);}// 初始化计数数组为0for (int i = 0; i < range; i++) {count[i] = 0;}// 统计每个元素出现的次数for (int i = 0; i < n; i++) {count[a[i] - min]++; // 使用元素值减去最小值作为计数数组的下标}// 重建排序后的数组int* output = (int*)malloc(n * sizeof(int));if (output == NULL) {// 内存分配失败处理free(count); // 释放已经分配的内存fprintf(stderr, "Memory allocation failed\n");exit(EXIT_FAILURE);}int index = 0; // 用于填充输出数组的索引for (int i = 0; i < range; i++) {// 对于每个在计数数组中出现的元素,将其填充到输出数组中while (count[i] > 0) {output[index] = i + min;index++;count[i]--;}}// 将排序后的数组复制回原数组for (int i = 0; i < n; i++) {a[i] = output[i];}// 释放动态分配的内存free(count);free(output);
}// 主函数,用于测试计数排序
int main() {int arr[] = {4, 2, 2, 8, 3, 3, 1};int n = sizeof(arr) / sizeof(arr[0]);// 调用计数排序函数CountSort(arr, n);// 打印排序后的数组for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
注释说明:
-
初始化最大值和最小值:
- 将数组的第一个元素赋值给最大值
max和最小值min。
- 将数组的第一个元素赋值给最大值
-
找到最大值和最小值:
- 遍历数组(从第二个元素开始,因为第一个元素已经用于初始化),更新最大值和最小值。
-
动态分配计数数组:
- 根据最大值和最小值计算计数数组的大小(范围),并动态分配内存。
- 检查内存分配是否成功,如果失败则处理错误(这里简单处理为退出程序)。
- 初始化计数数组为0。
-
统计每个元素出现的次数:
- 遍历输入数组,使用元素值减去最小值作为计数数组的下标,统计每个元素的出现次数。
-
重建排序后的数组:
- 动态分配一个大小为
n的输出数组。 - 使用两个循环:外循环遍历计数数组,内循环(
while循环)根据计数数组的值将元素填充到输出数组中。 - 注意,这里我们没有显式地计算前缀和,而是直接在填充输出数组时减少了计数数组的值。
- 动态分配一个大小为
-
将排序后的数组复制回原数组:
- 遍历输出数组,将排序后的元素复制回原数组。
-
释放内存:
- 释放计数数组和输出数组所占用的内存。
-
主函数:
- 初始化一个待排序的数组。
- 调用计数排序函数。
- 打印排序后的数组。
计数排序(Counting Sort)的时间复杂度和空间复杂度分析如下:
1.4 时间复杂度
-
查找最大值和最小值:
- 需要遍历整个数组一次,因此时间复杂度为 O ( n ) O(n) O(n)。
-
初始化计数数组并统计元素出现次数:
- 初始化计数数组的时间复杂度为 O ( k ) O(k) O(k),其中 k k k 是计数数组的大小(即输入数组中的最大值与最小值之差加一)。
- 遍历输入数组并统计元素出现次数的时间复杂度为 O ( n ) O(n) O(n)。
-
重建排序后的数组:
- 遍历计数数组并根据其值填充输出数组的时间复杂度为 O ( n + k ) O(n + k) O(n+k),但在最坏情况下(即所有元素都相同或非常接近时),这仍然可以看作是 O ( n ) O(n) O(n),因为 k k k 是由输入数据决定的,并且通常远小于 n n n 的数量级时,我们可以忽略 k k k 对时间复杂度的影响(但这取决于具体情况,如果 k k k 和 n n n 相近,则不能忽略)。
综上所述,计数排序的总时间复杂度在 O ( n + k ) O(n + k) O(n+k),其中 n n n 是输入数组的大小, k k k 是输入数据的范围(最大值与最小值之差加一)。在输入数据范围较小的情况下,计数排序是非常高效的。
1.5 空间复杂度
- 计数数组:需要额外一个大小为 k k k 的数组来存储每个元素的出现次数。
- 输出数组(如果单独分配):在重建排序后的数组时,如果分配了一个单独的输出数组,则需要额外的 n n n 个空间。但如前所述,这可以通过直接在原数组上重建来避免。
相关文章:
排序算法 -计数排序
文章目录 1. 计数排序(Counting Sort)1.1 简介1.2 计数排序的步骤1.3 计数排序C语言实现注释说明: 1.4 时间复杂度1.5 空间复杂度 1. 计数排序(Counting Sort) 1.1 简介 计数排序(Counting Sortÿ…...
Java学习,基本数据类型
变量就是申请内存来存储值,当创建变量的时候,需要在内存中申请空间。内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。Java 提供了八种基本数据类型,这些类型可以分为四大类:整数类型…...
单片机GPIO中断+定时器 软件串口通信
单片机GPIO中断定时器 软件串口通信 解决思路代码示例 解决思路 串口波特率9600bps,每个bit约为1000000us/9600104.16us; 定时器第一次定时时间设为52us即半个bit的时间,其目的是偏移半个bit时间,之后的每104us采样并读取1bit数据。使得采样…...
elementui el-table中给表头 el-table-column 加一个鼠标移入提示说明
前言 在使用el-table 表格中有些表格的表头需要加入一些提示,鼠标移入则出现提示,非常实用,我是通过el-table中的el-tooltip实现的,以下的效果预览 代码实现 <el-table ref"multipleTable" :data"data"…...
NVR小程序接入平台/设备EasyNVR多个NVR同时管理设备接入:海康NVR 3.0提示不在线如何处理?
在视频监控领域,设备的兼容性和互操作性一直是用户关注的重点。海康NVR管理平台EasyNVR作为一款轻量级的视频监控平台,凭借其强大的兼容性、可扩展性和丰富的功能,成为了公共安全领域“云平台”解决方案的杰出代表。然而,在实际应…...
datawhale11月组队学习 模型压缩技术2:PyTorch模型剪枝教程
文章目录 一、 prune模块简介1.1 常用方法1.2 剪枝效果1.3 二、三、四章剪枝测试总结 二、局部剪枝(Local Pruning)2.1 结构化剪枝2.1.1 对weight进行随机结构化剪枝(random_structured)2.1.2 对weight进行迭代剪枝(范…...
SOL链上Meme生态的崛起与未来#Dapp开发#链游#交易所#公链搭建
近年来,随着区块链技术的普及和NFT文化的流行,meme(网络迷因)逐渐成为区块链生态中的重要组成部分。meme不仅是一种互联网文化符号,更逐步渗透进了去中心化金融(DeFi)、NFT和元宇宙等多个领域&a…...
部署Apache Doris
官方文档:https://doris.apache.org/zh-CN/installing/compilation.html 一、编译 使用 Docker 开发镜像编译(推荐) 1.拉取镜像 #下载 Docker 最新主干版本代码,会随主干版本不断更新。 $ docker pull apache/incubator-doris:…...
ElasticSearch-全文检索(一)基本介绍
简介 Elasticsearch:官方分布式搜索和分析引擎 | Elastic 全文搜索属于最常见的需求,开源的Elasticsearch是目前全文搜索引擎的首选。 它可以快速地储存、搜索和分析海量数据。维基百科、StackOverflow、Github都采用它 Elastic的底层是开源库Lucene。但…...
paramiko 库实现的暴力破解 SSH 密码
import paramiko import optparse import threading import time from threading import Thread, BoundedSemaphore# 用paramiko暴力破解SSH密码 # 最大并发连接尝试的数量,可根据实际情况调整,适当减小可降低对目标服务器的压力以及减少多线程同步问题出…...
Python 操作 Elasticsearch 全指南:从连接到数据查询与处理
文章目录 Python 操作 Elasticsearch 全指南:从连接到数据查询与处理引言安装 elasticsearch-py连接到 Elasticsearch创建索引插入数据查询数据1. 简单查询2. 布尔查询 更新文档删除文档和索引删除文档删除索引 批量插入数据处理分页结果总结 Python 操作 Elasticse…...
Jarvis March算法详解及Python实现(附设计模式案例)
目录 Jarvis March算法详解及Python实现(附设计模式案例)第一部分:Jarvis March算法概述与原理1.1 什么是Jarvis March算法?1.2 算法原理1.3 算法流程1.4 时间复杂度第二部分:Jarvis March算法的Python实现(面向对象设计)2.1 面向对象设计2.2 代码实现2.3 代码解释第三部…...
AIGC中的文本风格迁移:基于深度学习的实现
引言 文本风格迁移是自然语言处理领域的一个重要研究方向,它可以将文本从一种风格转换为另一种风格,同时保留其原有的内容。随着深度学习技术的发展,文本风格迁移的方法变得越来越先进和高效。本文将探讨基于序列到序列模型(Seq2…...
丹摩征文活动 |【前端开发】HTML+CSS+JavaScript前端三剑客的基础知识体系了解
前言 🌟🌟本期讲解关于HTMLCSSJavaScript的基础知识,小编带领大家简单过一遍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 …...
响应“一机两用”政策 落实政务外网安全
在数字化时代,政务办公外网安全的重要性日益凸显,特别是在“一机两用”的背景下,即同一台终端既要处理政务内网的数据,又要访问互联网,这对网络安全提出了更高的要求。深信达SPN安全上网方案,即反向沙箱技术…...
通过JS删除当前域名中的全部COOKIE教程
有时候需要通过JS来控制一下网站的登录状态,就例如:网站登出功能,我们可以直接通过JS将所有COOKIE删除,COOKIE删除之后,网站自然也就退出了。 那么今天我就给大家分享一段JS的函数,通过调用这段函数就可以实现删除COO…...
Flutter:Widget生命周期
StatelessWidget:无状态部件的生命周期 import package:flutter/material.dart;void main() {runApp(App()); }class App extends StatelessWidget {overrideWidget build(BuildContext context) {return MaterialApp(home: MyHomePage(title: MyHome),);} }class M…...
Flutter:Dio下载文件到本地
import dart:io; import package:dio/dio.dart;main(){// 创建dio对象final dio Dio();// 下载地址var url https://*******.org/files/1.0.0.apk;// 手机端路径String savePath Directory.systemTemp.path/ceshi.apk;print(savePath);downLoad(dio,url,savePath); }downLo…...
[⑧5G NR]: PBCH payload生成
本篇博客记录下5G PBCH信道中payload数据的生成方式。PBCH payload一共32个比特,基本结构如下图: 根据SSB PDU中bchPayloadFlag的值有三种方式得到PBCH payload。 bchPayloadFlag 0:全部32比特由MAC层提供。 bchPayloadFlag 1:M…...
查看解决端口占用,以及docker解决端口占用的原理
在软件开发和部署过程中,端口占用是一个常见的问题。以下是查看和解决端口占用问题的完整解决方案: 一、查看端口占用情况 1. 在 Linux 系统中 方法一:使用 lsof 命令 sudo lsof -i:<端口号>输出信息中会显示占用端口的进程名称、PI…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
