【数据结构与算法】排序算法(下)——计数排序与排序总结

news2024/12/24 10:11:39

写在前面

书接上文:【数据结构与算法】排序算法(中)——交换排序之快速排序

文章主要讲解计数排序的细节与分析源码。之后进行四大排序的总结。


文章目录

  • 写在前面
  • 一、计数排序(非比较排序)
          • 代码的实现:
  • 二、排序总结
    • 2.1、稳定性
    • 3.2、排序算法复杂度及稳定性总结


一、计数排序(非比较排序)

思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

操作步骤:

  1. 确定范围:首先,确定待排序数组中元素的取值范围,即最小值和最大值。假设数据的值在 [0, K-1] 范围内。

  2. 创建计数数组:根据元素的取值范围创建一个计数数组count,该数组的每个索引代表数组中某个元素的值,值为该元素出现的次数。例如,count[i] 表示元素i出现的次数。

  3. 统计元素出现次数:遍历原始数组,对每个元素x,将 count[x] 增加 1。这样,count 数组就记录了每个元素的出现次数。

  4. 重建排序数组:遍历count数组,根据每个元素的出现次数将元素放入最终的排序数组中。

在这里插入图片描述
假设有一个待排序数组[4, 2, 2, 8, 3, 3, 1]

步骤 1:确定数据范围
最小值1最大值8,因此我们需要创建一个长度为 8 的计数数组 count,用于记录 18 每个元素的出现次数

步骤 2:设计计数数组
步骤1中确定了数组开辟长度为 8。在8个长度中,我们应该把下标0就设置存储最小元素出现的次数,接下来的下标就对应着当前数据-最小元素的下标

  • 举个例子:
    在当前数组中:1是最小元素,那么计数数组的0下标就对应着统计1元素出现的次数,那么元素8对应的小标就是8-1的位置,即下标7才是计算元素8出现的次数。

步骤 3:统计每个元素的出现次数
遍历原始数组 [4, 2, 2, 8, 3, 3, 1],统计每个元素出现的次数,并更新计数数组:

  • 数字 4count[4-1] = count[3] 增加 1count[3] = 1
  • 数字 2count[2-1] = count[1] 增加 1count[1] = 1
  • 数字 2count[2-1] = count[1] 增加 1count[1] = 2
  • 数字 8count[8-1] = count[7] 增加 1count[7] = 1
  • 数字 3count[3-1] = count[2] 增加 1count[2] = 1
  • 数字 3count[3-1] = count[2] 增加 1count[2] = 2
  • 数字 1count[1-1] = count[0] 增加 1count[0] = 1

统计完成后,count 数组变为:count = [1, 2, 2, 1, 0, 0, 0, 1]
在这里插入图片描述
这表示

  • 数字 1 出现了 1
  • 数字 2 出现了 2
  • 数字 3 出现了 2
  • 数字 4 出现了 1
  • 数字 5 没有出现
  • 数字 6 没有出现
  • 数字 7 没有出现
  • 数字 8 出现了 1

步骤 4:根据计数数组重建排序数组
接下来,我们可以根据 count 数组来重建排序数组:

从 count 数组中取出每个数字出现的次数,然后把它们按顺序放入结果数组中。

  • count[0] = 1,因此排序数组中加入一个 1

  • count[1] = 2,因此排序数组中加入两个2

  • count[2] = 2,因此排序数组中加入两个 3

  • count[3] = 1,因此排序数组中加入一个 4

  • count[4] = 0,跳过。

  • count[5] = 0,跳过。

  • count[6] = 0,跳过。

  • count[7] = 1,因此排序数组中加入一个 8

重建后的原数组: [1, 2, 2, 3, 3, 4, 8]
在这里插入图片描述

代码的实现:
void countingSort(int* arr, int len) {
	int min = arr[0], max = arr[0];//

	for (int i = 0; i < len; i++) {//找最大最小值
		if (arr[i] > max) {
			max = arr[i];
		}
		if (arr[i] < min) {
			min = arr[i];
		}
	}
	
	int* countArr = (int*)calloc((max - min) + 1, sizeof(int));//创建一个计数数组,用于记录每个数字出现的次数。
	
	for (int i = 0; i < len; i++) {//计数
		countArr[arr[i] - min]++;
	}
	int j = 0;
	for (int i = 0; i < (max - min) + 1; i++) {//排序
		/*if (countArr[i] <= 0) {
			;
		}
		else {
			arr[j++] = i + min;
			countArr[i]--;
			i--;
		}*/
		while (countArr[i]--) {
			arr[j++] = i + min;
		}
	}
}
  • 需要注意的细节在最小值与最大值的定义时,需要初始化为数组中的元素,只有这样才会对排序不会造成影响。
  • 在排序中,可以设计一个循环来进行辅助排序,也可以使用条件判断语句排序,这二者的时间复杂度都是一样的
  • 计数循环中,使用了arr[i] - min,这样是min最小的值设置为数组的开头,即下标为0的位置,这样就可以避免计数数组开辟过多的空间,也可以更好的适配含负数的数据排序

计数排序的特性总结:

  1. 计数排序在数据范围集中时,效率很高,甚至可以达到O(N),但是适用范围及场景有限。
  2. 时间复杂度:O(MAX(N,范围))
  3. 空间复杂度:O(范围)
  4. 稳定性:稳定

二、排序总结

2.1、稳定性

在不才写的三篇排序笔记中,不才在每个排序中都有写特性总结,这其中有稳定性,在排序中,稳定性不是说是这个排序是否每次都稳定排序,而是指在排序过程中,若两个元素的值相等,它们在排序后的相对顺序保持不变。
在这里插入图片描述
我们排序 { 1 2 3 1 4 } 这组数据,在这组数据中,如果我们使用的是稳定的排序排序完成后红色的1一定会保持在橙色的1后面,如:{ 1 1 2 3 4 }如果不能确保每次排序红色的1在橙色的1后面,那就是不稳定排序如:{ 1 1 2 3 4 }


3.2、排序算法复杂度及稳定性总结

在这里插入图片描述

在这里插入图片描述


ps:
排序算法(上)——插入排序与选择排序
排序算法(中)——交换排序与归并排序

以上就是本章所有内容。若有勘误请私信不才。万分感激💖💖 如果对大家有帮助的话,就请多多为我点赞收藏吧~~~💖💖
请添加图片描述

ps:表情包来自网络,侵删🌹

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

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

相关文章

Unity全局雾效

1、全局雾效是什么 全局雾效&#xff08;Global Fog&#xff09;是一种视觉效果&#xff0c;用于在3D场景中模拟大气中的雾气对远处物体的遮挡 它通过在场景中加入雾的效果&#xff0c;使得距离摄像机较远的物体看起来逐渐被雾气覆盖&#xff0c;从而创造出一种朦胧、模糊的视…

Kafka Streams 在监控场景的应用与实践

作者&#xff1a;来自 vivo 互联网服务器团队- Pang Haiyun 介绍 Kafka Streams 的原理架构&#xff0c;常见配置以及在监控场景的应用。 一、背景 在当今大数据时代&#xff0c;实时数据处理变得越来越重要&#xff0c;而监控数据的实时性和可靠性是监控能力建设最重要的一环…

数据分析思维(五):分析方法——假设检验分析方法

数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…

解读DiffusionNER: Boundary Diffusion for Named Entity Recognition

content 摘要1. 图1图21. 上方&#xff1a;扩散过程与实体边界2. 下方&#xff1a;网络结构&#xff08;Sentence Encoder Entity Decoder&#xff09;3. 关键思想小结 摘要 主要内容分为四个部分&#xff1a; 模型定位与基本原理&#xff1a; 提出了DiffusionNER模型将命名…

【QSS样式表 - ⑥】:QPushButton控件样式

文章目录 QPushBUtton控件样式QSS示例 QPushBUtton控件样式 常用子控件 常用伪状态 QSS示例 代码&#xff1a; QPushButton {background-color: #99B5D1;color: white;font-weigth: bold;border-radius: 20px; }QPushButton:hover {background-color: red; }QPushButton:p…

数字经济下的 AR 眼镜

目录 1. &#x1f4c2; AR 眼镜发展历史 1.1 AR 眼镜相关概念 1.2 市面主流 XR 眼镜 1.3 AR 眼镜大事记 1.4 国内外 XR 眼镜 1.5 国内 AR 眼镜四小龙 2. &#x1f531; 关键技术 2.1 AR 眼镜近眼显示原理 2.2 AR 眼镜关键技术 2.3 AR 眼镜技术难点 3. &#x1f4a…

smb和nfs双栈协议共享目录

1 简介 NFS和SAMBA协议都是文件共享&#xff0c;Linux客户端常用于NFS协议访问远程共享目录&#xff0c;Windows客户端常用于SAMBA协议访问远程共享目录。 2 环境 合计使用三台服务器&#xff0c;服务器都位于同一个子网&#xff08;10.0.0.0/19&#xff09;、同一个安全组…

Day13 用Excel表体验梯度下降法

Day13 用Excel表体验梯度下降法 用所学公式创建Excel表 用Excel表体验梯度下降法 详见本Day文章顶部附带资源里的Excel表《梯度下降法》&#xff0c;可以对照表里的单元格公式进行理解&#xff0c;还可以多尝试几次不同的学习率 η \eta η来感受&#xff0c;只需要更改学习率…

Python获取系统负载并打印折线图

#! /opt/py36/bin/python import psutil import matplotlib.pyplot as plt import time# 创建一个空列表&#xff0c;用于存储负载数据 load_data []# 循环收集负载数据 while True:# 获取当前系统负载load_avg psutil.getloadavg()# 将平均负载添加到load_data列表中load_da…

RCE 命令执行漏洞 过滤模式 基本的过滤问题 联合ctf题目进行实践

前言 知道RCE 命令执行分为 代码执行 和 命令执行 原理 &#xff1a; 就是用户的输入被当做命令或者代码执行了 从而造成了危害 代码执行 除了eval php代码执行漏洞的函数还有 eval()、a ssert()、 preg_replace()、 create_function()、 array_map()、 call_user_func(…

Leetcode打卡:考场就坐

执行结果&#xff1a;通过 题目&#xff1a; 855 考场就坐 在考场里&#xff0c;有 n 个座位排成一行&#xff0c;编号为 0 到 n - 1。 当学生进入考场后&#xff0c;他必须坐在离最近的人最远的座位上。如果有多个这样的座位&#xff0c;他会坐在编号最小的座位上。(另外&am…

数据结构(哈希表(上)纯概念版)

前言 在软件开发和计算机科学中&#xff0c;数据结构的选择直接影响到程序的性能和效率。不同的数据结构适用于不同的场景&#xff0c;合理地选择合适的数据结构是高效编程的关键之一。哈希表&#xff08;哈希表&#xff08;Hash Table&#xff09;作为一种高效的键值对存储结…

【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…

深入解析 Spring WebFlux:原理与应用

优质博文&#xff1a;IT-BLOG-CN WebFlux 是 Spring Framework 5 引入的一种响应式编程框架&#xff0c;和Spring MVC同级&#xff0c;旨在处理高并发和低延迟的非阻塞应用。这是一个支持反应式编程模型的新Web框架体系。 顺便一提&#xff0c;Spring Cloud Gateway在实现上是…

C语言基础——指针(4)

一&#xff0e; 字符指针变量 字符指针变量的使用和整型指针变量的使用方法相似&#xff0c;以下是其基本使用方法的例子&#xff1a; &#xff08;1&#xff09;字符指针变量还有一种使用方法&#xff1a; const char* p "abcd" 需…

『 Linux 』高级IO (一)

文章目录 内容回顾及铺垫五种IO模型不同类型IO的区别非阻塞IOfcntl( ) 多路转接 - select( )select( ) 的基本使用 - SelectServer服务器 内容回顾及铺垫 在博客『 Linux 』基础IO/文件IO (万字)中介绍了对IO的认识; IO实际上为Input/Output,输入输出; 以网络协议栈的视角来看,…

Spark-Streaming集成Kafka

Spark Streaming集成Kafka是生产上最多的方式&#xff0c;其中集成Kafka 0.10是较为简单的&#xff0c;即&#xff1a;Kafka分区和Spark分区之间是1:1的对应关系&#xff0c;以及对偏移量和元数据的访问。与高版本的Kafka Consumer API 集成时做了一些调整&#xff0c;下面我们…

「下载」智慧城市包括哪些方面:大数据公共服务平台、城市运行指挥中心、城市综合治理平台、城市体检综合运营平台解决方案

在当今信息化高速发展的时代&#xff0c;智慧城市已成为全球城市发展的新趋势。系列全面而创新的智慧城市解决方案&#xff0c;旨在助力城市实现智慧化转型&#xff0c;提升城市管理效率&#xff0c;增强市民生活质量。 智慧城市最新解决方案&#xff0c;标准规范顶层设计指南、…

ChatGPT生成接口文档实践案例(二)

不难发现&#xff0c;两个方案都出色地完成了接口文档的生成&#xff0c;但笔者更喜欢Response 2的表达&#xff0c;因为其描述更加全面。 还可以让ChatGPT生成符合OpenAPI 3.0规范的接口文档&#xff0c;以便于项目相关成员阅读&#xff0c;如图5-13所示。 为什么要生成OpenAP…

【解决】Linux更新系统内核后Nvidia-smi has failed...

问题概述 由于服务器(操作系统为 RedHat 9)宕机&#xff0c;重启后&#xff0c;系统内核自动更新了&#xff0c;然后输入 nvidia-smi 发现报了下面的异常&#xff1a; NVIDIA-SMI has failed because it couldnt communicate with the NVIDIA driver. Make sure that the late…