【数据结构】排序算法系列——计数排序(附源码+图解)

news2024/9/28 11:45:12

计数排序

顾名思义:统计每个数据出现的次数。

算法思想

我们根据《算法导论》中给出对于计数排序的讨论:

对每一个输入元素 x, 确定小于 x 的元素个数。利用这一信息,就可以直接把 x 放到它在输出数组中的位置上了。例如,如果有 17 个元素小于 x , 则 x 就应该在第18个输出位置上。当有几个元素相同时,这一方案要略做修改。因为不能把它们放在同一个输出位置上。

它的工作过程分为三个步骤:

  1. 计算每个数出现了几次;
  2. 求出每个数出现次数的 前缀和;
  3. 利用出现次数的前缀和,从右至左计算每个数的排名。

图解

在这里插入图片描述

在这里插入图片描述

C语言代码分析
#define CRT_SECURE_NO_WARNINGS 1
//计数排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void CountingSort(int arr[], int size)
{
	//找到数组中的最大值和最小值

	int max = arr[0];
	int min = arr[0];
	for (int i = 1; i < size; i++)//进行
	{
		if (arr[i] > max)//如果元素大于此时的最大值,则更新最大值
			max = arr[i];
		if (arr[i] < min)//如果元素小于此时的最小值,则更新最小值
			min = arr[i];
	}

	//创建计数数组,并初始化为0
	int range = max - min - 1;
	int* count = (int*)calloc(range, sizeof(int));

	//统计每个元素的出现次数
	for (int i = 1; i < size; i++)
	{
		count[arr[i] - min]++;//将元素的值作为下标,出现的次数作为值
	}

	//进行累加操作
	for (int i = 1; i < range; i++)
	{
		count[i] += count[i - 1];
	}

	//创建输出数组,并将元素按照排序结果依次放入
	int* output = (int*)malloc(size * sizeof(int));
	for (int i = size - 1; i >= 0; i--)
	{
		output[count[arr[i] - min] - 1] = arr[i];//将元素放入输出数组中
		count[arr[i] - min]--;//将元素的出现次数减1,符合C语言下标规则
	}

	//将排序结果放回原数组
	for (int i = 0; i < size; i++)
	{
		arr[i] = output[i];
	}

	free(count);
	free(output);
}

时间复杂度

我们发现这种算法实际上并没有进行比较——它是一个非比较排序算法。它主要进行的是一个分类的操作,将相同的数分在一类,在进行完分类后,再针对分类出来的代表数进行整体排序。但实际上这样的排序会有一个缺陷——如果相同的数过少,或者说整个数据组的同一性过小,那么实际上分类过程的意义也就会随之变小——从而还是主要依靠排序来进行算法的完成。这里我们就会谈及计数排序的局限性——它适用于范围集中且范围不大的整形数组排序。

image-20240817171439272

计数排序的下界优于O(nlogn),因为它并不是一个比较排序算法。事实上,它的代码中完全没有输人元素之间的比较操作。相反,计数排序是使用输人元素的实际值来确定其在数组中的位置。当我们脱离了比较排序模型的时候,**O(nlogn)**这一下界就不再适用了。

我们一般根据数组的范围来判断其时间复杂度,为此我们可以给出大致的复杂度:

O(n+w),其中w代表待排序数据的值域大小。

稳定性

计数排序的一个重要性质就是它是稳定的:具有相同值的元素在输出数组中的相对次序与它们在输人数组中的相对次序相同。也就是说,对两个相同的数来说,在输入数组中先出现的数,在输出数组中也位于前面。

计数排序的稳定性很重要的另一个原因是:计数排序经常会被用作基数排序算法的一个子过程。我们将在下一节中看到,为了使基数排序正确运行,计数排序必须是稳定的

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

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

相关文章

秋招即将来临,AIGC 产品经理 快速入门方法论

AIGC 产品经理是什么 AIGC 产品经理是人工智能与大数据技术融合背景下应运而生的一种新型职业&#xff0c;负责从 AI 产品的设计、开发到推广的全过程&#xff0c;确保其顺利推向市场并实现良好的商业价值。 更具体地说&#xff0c;AIGC 产品经理就是将 AI 能生产内容的能力完…

【高景一号卫星】

高景一号卫星 高景一号卫星是中国自主研发的一系列高分辨率商业遥感卫星&#xff0c;旨在满足全球民用遥感影像市场的需求。以下是对高景一号卫星的详细介绍&#xff1a; 一、基本信息 名称&#xff1a;高景一号&#xff08;SuperView-1, SV-1&#xff09;发射时间&#xf…

数据库管理-第244期 一次无法switchover的故障处理(20240928)

数据库管理244期 2024-09-28 数据库管理-第244期 一次无法switchover的故障处理&#xff08;20240928&#xff09;1 问题展现2 问题排查与处理2.1 问题12.2 问题2 3 问题分析4 总结 数据库管理-第244期 一次无法switchover的故障处理&#xff08;20240928&#xff09; 作者&…

TimeMOE: 使用稀疏模型实现更大更好的时间序列预测

传统上,预测这些趋势涉及针对每种情况的专门模型。最近的进展指向了可以处理广泛预测问题的"基础模型"。 这是9月份刚刚发布的论文TimeMOE。它是一种新型的时间序列预测基础模型,“专家混合”(Mixture of Experts, MOE)在大语言模型中已经有了很大的发展&#xff0c…

如何在ChatGPT的帮助下,使用“逻辑回归”技巧完成论文写作?

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 逻辑回归作为一种统计分析工具广泛应用&#xff0c;以解决研究中的分类问题。其主要作用在于探讨和量化自变量对因变量的影响&#xff0c;从而揭示潜在的因果关系。 在论文写作中&…

无人驾驶车联网5G车载路由器应用

无人驾驶车联网中&#xff0c;5G车载路由器的应用起到了至关重要的作用。以下是关于5G车载路由器在无人驾驶车联网中应用的详细分析&#xff1a; 5G车载路由器具备极低的时延特性&#xff0c;能够实现车与车之间、车与基础设施之间的快速通信。这对于无人驾驶技术尤为重要&…

策略模式与工厂模式的区别

《策略模式与工厂模式的区别》 策略模式&#xff08;Strategy Pattern&#xff09; 和 工厂模式&#xff08;Factory Pattern&#xff09; 都是常见的设计模式&#xff0c;虽然它们在设计目标上有一些相似之处&#xff0c;如解耦代码、增强扩展性&#xff0c;但它们的应用场景和…

做中视频计划,哪里找素材?推荐几个热门中视频素材下载网站

在做中视频计划时&#xff0c;寻找合适的素材至关重要。抖音上那些热门的中视频素材都是从哪里下载的呢&#xff1f;以下五大高清素材库值得收藏&#xff0c;赶紧来看看吧&#xff01; 蛙学网 蛙学网提供了百万级的中视频素材&#xff0c;质量高且是4K高清无水印&#xff0c;视…

crypt.h:No such file or directory 报错处理

crypt.h&#xff1a;No such file or directory 报错处理 前言&#xff1a;本文初编辑于2024年9月28日 CSDN主页&#xff1a;https://blog.csdn.net/rvdgdsva 博客园主页&#xff1a;https://www.cnblogs.com/hassle 博客园本文链接&#xff1a;https://www.cnblogs.com/has…

0基础学前端 day6 -- 搭建github pages静态网址

标题&#xff1a;如何通过 GitHub Pages 创建一个静态网站 GitHub Pages 是 GitHub 提供的一项免费服务&#xff0c;允许用户从 GitHub 仓库中托管静态网站。对于开发者和非开发者来说&#xff0c;这都是一个极其便利的工具&#xff0c;用于创建和发布个人博客、项目文档或作品…

[leetcode刷题]面试经典150题之9python哈希表详解(知识点+题合集)

为了方便理解哈希表&#xff0c;我们先从python中的字典讲起。 字典 (Dictionary) 字典是 Python 中一种内置的数据结构&#xff0c;它是一种 键值对&#xff08;key-value pair&#xff09;存储形式。每个键&#xff08;key&#xff09;都有一个对应的值&#xff08;value&a…

100个Transformer面试题,附答案!收藏这一篇就够了!

前言 Transformer是一种用于自然语言处理&#xff08;NLP&#xff09;和其他序列到序列&#xff08;sequence-to-sequence&#xff09;任务的深度学习模型架构&#xff0c;它在2017年由Vaswani等人首次提出。Transformer架构引入了自注意力机制&#xff08;self-attention mec…

力扣 简单 112.路径总和

文章目录 题目介绍题解 题目介绍 题解 class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {// 只在最开始的时候判断树是否为空if (root null) {return false;}targetSum - root.val;if (root.left null && root.right null) { // root 是…

zookeeper 服务搭建(集群)

准备3台虚拟机&#xff0c;ip分别是&#xff1a; 192.168.10.75 192.168.10.76 192.168.10.77 准备3个节点 mkdir /usr/local/cluster cd /usr/local/cluster git clone https://gitee.com/starplatinum111/apache-zookeeper-3.5.9-bin.git 重命名文件夹 mv apache-zookeeper…

uniapp踩坑 tabbar页面数据刷新了但视图没有更新

问题描述&#xff1a; 有个uni-data-checkbox组件&#xff0c;两个选项&#xff1a;选项1和选项2&#xff08;对应的value值分别为1和2&#xff09;&#xff0c;v-model绑定属性名为value 两个tabbar页面&#xff1a;tab1&#xff0c;tab2。 tab1页面有个逻辑是在onShow中刷新v…

【开源免费】基于SpringBoot+Vue.JS新闻推荐系统(JAVA毕业设计)

本文项目编号 T 056 &#xff0c;文末自助获取源码 \color{red}{T056&#xff0c;文末自助获取源码} T056&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

Docker官网新手入门教程:从零开始玩转容器

大家好&#xff0c;今天咱们来聊聊Docker这个时髦的容器技术。 什么是Docker&#xff1f; Docker就像是一个打包快递的师傅&#xff0c;它能把你的应用程序和它所依赖的一切打包成一个标准的容器。这个容器可以在任何安装了Docker引擎的机器上运行&#xff0c;而且不会受到底…

9.28今日错题解析(软考)

目录 前言面向对象技术——UML软件工程——软件能力成熟度模型&#xff08;CMM&#xff09;程序设计语言——编译 前言 这是用来记录我备考软考设计师的错题的&#xff0c;今天知识点为UML、软件能力成熟度模型&#xff08;CMM&#xff09;和编译&#xff0c;大部分错题摘自希…

Linux基础(三):安装CentOS7

1.分区设置 由于使用 GPT 的关系&#xff0c; 因此根本无须考虑主/延伸/逻辑分区的差异。CentOS 默认使用 LVM 的方式来管理你的文件系统。使用GPT进行分区&#xff1a; 开机管理程序&#xff08; boot loader&#xff09; 使用CentOS 7.x默认的grub2软件。 2.各种分区格式 …

Redis: 特点,优势,与其他产品的区别,版本演进,以及高并发原理

入门Redis概述 1 &#xff09;选择Redis是因为其高性能 因为 Redis 它数据存储的机制是存在内存中的&#xff0c;减少了传统关系数据库的磁盘IO它是单线程的保证了原子性&#xff0c;它还提供了事务&#xff0c;锁等相关的机制 2 &#xff09;Redis 环境安装配置 linux 或 d…