数据结构—排序算法(归并非比较)

news2024/11/18 14:25:30

目录

1、 归并排序

1.1 基本思想

1.2 归并排序递归方式的实现

1.3 归并排序非递归方式的实现

1.4 归并排序的特性总结

2、计数排序

2.1 计数排序基本思想

2.2 计数排序的实现

2.3 计数排序的特性总结:


1、 归并排序

1.1 基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有 序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

1.2 归并排序递归方式的实现

归并排序相当于后序遍历,此时可以求出中间位置,控制归并区间

【begin , mid】【mid + 1,end】,递归,直到只有一个值,返回左右区间,对左右区间进行归并,完成后返回,在对右区间递归,递归完后,在返回,归并左右区间。

void _MergeSort(int* a,int begin,int end,int* tmp) {
	if (begin >= end) {
		return;
	}
	int mid = (begin + end) / 2;
	_MergeSort(a, begin, mid, tmp);
	_MergeSort(a, mid + 1, end, tmp);
	//归并
	int begin1 = begin, end1 = mid;
	int begin2 = mid + 1, end2 = end;
	int tmpPos = begin1;
	while (begin1 <= end1 && begin2 <= end2) {
		if (a[begin1] > a[begin2]) {
			tmp[tmpPos++] = a[begin2++];
		}
		else {
			tmp[tmpPos++] = a[begin1++];
		}
	}
	while (begin1 <= end1) {
		tmp[tmpPos++] = a[begin1++];
	}
	while (begin2 <= end2) {
		tmp[tmpPos++] = a[begin2++];
	}
	memcpy(a + begin, tmp + begin, (end - begin + 1) * sizeof(int));
}
void MergeSort(int* a, int n) {
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL) {
		printf("malloc fail\n");
		exit(-1);
	}
	_MergeSort(a, 0, n - 1, tmp);

	free(tmp);
}

1.3 归并排序非递归方式的实现

问题分析:

快排类似于先序遍历,先处理 keyi 值,因此可以利用数据结构栈和队列记录后续区间,进行非递归实现,由于其keyi值先进行了处理,并不关注左右起始位置是否记录,依次进行左右位置出栈入栈数据处理,最终获得有序序列。

但是归并排序,在出栈获得序列左右边起始位置后,处理完左边子序列和右边子序列后,仍需对原序列再次进行归并处理,而此时栈内已不再有原序列,因此借助数据结构方式进行实现非递归是困难的。

 解决方法:

此时可借助循环,控制起始序列方式,进行处理。此时需要控制其两组数据如果第一组以达到边界,下一组数据便会越界,出现越界访问错误。

void MergeSortNonR(int* a, int n) {
	assert(a);
	int* tmp = (int*)malloc(sizeof(int) * n);
	assert(tmp);
	int gap = 1;
	while (gap < n) {
		for (int i = 0; i < n; i += 2 * gap) {
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			//修正边界
			if (end1 >= n) {
				end1 = n - 1;
				//begin2、end2 修正为一个不存在的空间
				begin2 = n;
				end2 = n - 1;
			}
			else if (begin2 >= n) {
				begin2 = n;
				end2 = n - 1;
			}
			else if (end2 >= n) {
				end2 = n - 1;
			}
			int tmpPos = begin1;
			while (begin1 <= end1 && begin2 <= end2) {
				if (a[begin1] > a[begin2]) {
					tmp[tmpPos++] = a[begin2++];
				}
				else {
					tmp[tmpPos++] = a[begin1++];
				}
			}
			while (begin1 <= end1) {
				tmp[tmpPos++] = a[begin1++];
			}
			while (begin2 <= end2) {
				tmp[tmpPos++] = a[begin2++];
			}
		}
		memcpy_s(a, sizeof(int) * n, tmp, sizeof(int) * n);
		gap *= 2;
	}
	free(tmp);
}

1.4 归并排序的特性总结

  1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(N)
  4. 稳定性:稳定

2、计数排序

2.1 计数排序基本思想

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

1. 统计相同元素出现次数

2. 根据统计的结果将序列回收到原来的序列中

3.局限性:
1)如果是浮点数、字符串就不能排序
2)如果数据范围很大,空间复杂度高,不合适
3)如果使用绝对映射,容易浪费空间,且负数不便于处理

2.2 计数排序的实现

优化,统计最小,将其所计数映射位置减去最小值,可以相对减少空间浪费,同时可以排序负数

void CountSort(int* a, int n) {
	assert(a);
	int min = a[0], max = a[0];
	for (int i = 1; i < n; i++) {
		if (a[i] < min) {
			min = a[i];
		}
		if (a[i] > max) {
			max = a[i];
		}
	}
	int range = max - min + 1;
	int* count = (int*)malloc(sizeof(int) * range);
	assert(count);
	memset(count, 0, sizeof(int) * range);
	//计数
	for (int i = 0; i < n; i++) {
		count[a[i] - min]++;
	}
	//回写排序
	int j = 0;
	for (int i = 0; i < range; i++) {
		while (count[i]--) {
			a[j++] = i + min;
		}
	}
}

2.3 计数排序的特性总结:

  • 计数排序在数据范围集中时,效率很高,但是适用范围及场景有限。
  • 时间复杂度:O(MAX(N,范围))
  • 空间复杂度:O(范围) 比特就业课
  • 稳定性:稳定

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

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

相关文章

反射技术

一、获取Class对象 方式一&#xff1a;类名.class // 方式一&#xff1a;类名.classClass<Student> studentClass Student.class;System.out.println(studentClass);方式二&#xff1a;static Class forName(String fullNameWithPackage) 需要注意的是&#xff0c;for…

MAAS搭建

要求 https://maas.io/docs/installation-requirements 安装maas sudo snap install --channel=3.3 maas安装postgres sudo apt update -y sudo apt install -y postgresql设置数据库 sudo -i -u postgres psql -c "CREATE USER \"$MAAS_DBUSER\" WITH E…

深化企业数据智能应用 用友敢当“急先锋”

本篇文章来源于趣味科技v &#xff0c;作者完美主义 面对扑面而来的数字经济时代&#xff0c;一场轰轰烈烈的企业数智化转型正进行得如火如荼。 然而许多企业虽然明知道数智化转型势在必行&#xff0c;但是又担忧自己不具备相关能力。这些企业在数据和智能上面临哪些挑战&…

华为OD机试之TLV解析Ⅰ(Java源码)

TLV解析Ⅰ 题目描述 TLV编码是按[Tag Length Value]格式进行编码的&#xff0c;一段码流中的信元用Tag标识&#xff0c;Tag在码流中唯一不重复&#xff0c;Length表示信元Value的长度&#xff0c;Value表示信元的值。 码流以某信元的Tag开头&#xff0c;Tag固定占一个字节&…

在SecureCRT下使用sz下载和rz上传文件

安装命令&#xff1a;yum install lrzsz 在某些情况下使用ftp不能上传和下载到指定的目录&#xff0c;特别在项目中&#xff0c;比较麻烦&#xff0c;所以可以使用sz和rz命令可以实现在SecureCRT中上传下载 配置上传下载目录&#xff1a;选择某个session标签&#xff0c;点击…

YOLO V3 SPP ultralytics 第四节:YOLO V3 SPP网络的搭建

目录 1. 介绍 2. 代码介绍 2.1 create_modules 部分 2.1.1 不同层的处理 2.1.2 信息的融合 2.1.3 yolo 层的处理 2.2 get_yolo_layers 2.3 前向传播 3. 完整代码 1. 介绍 根据 上一节 解析的cfg文件&#xff0c;本章将配置文件cfg 搭建YOLO V3 SPP网络 本章的代码经过…

VuePress V1 添加 Vssue 评论功能

文章目录 前言选型集成Vssue安装创建 Github OAuth App配置插件使用 Vssue 组件自动创建 Issue 小结参考文献 前言 我的第二本开源电子书《后台开发命令 365》上线啦。 使用 VuePress 将之前记录的后台常用 Linux 命令博文整理成一个系统的开源电子书&#xff0c;方便阅读&am…

LeetCode 周赛 346(2023/05/21)仅 68 人 AK 的最短路问题

本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 提问。 LeetCode 单周赛第 345 场 体验一题多解的算法之美 单周赛 345 概览 T1. 删除子串后的字符串最小长度&#xff08;Easy&#xff09; 标签&#xff1a;栈 T2. 字典序最小回…

Sui基金正在招聘亚太地区市场经理,期待您的加入

Sui基金会致力于支持Sui网络的开发、增长和推广使用。Sui是基于第一原理重新设计和构建而成的L1公有链&#xff0c;旨在为创作者和开发者能够构建从游戏到金融的独特Web3体验。 Sui基金会三大去中心化原则&#xff1a;拥抱透明且公平的竞争环境、公开沟通以建立信任的文化&…

传染病学模型 | Matlab实现SIR传染病学模型 (SIR Epidemic Model)

文章目录 效果一览基本描述模型介绍程序设计参考资料效果一览 基本描述 传染病学模型 | Matlab实现SIR传染病学模型 (SIR Epidemic Model) 模型介绍 SIR模型是一种基本的传染病学模型,用于描述一个人群中某种传染病的传播情况。SIR模型假设每个人可以被感染,感染后会进入恢复…

Kibana:创建你的第一个仪表板

了解从你自己的数据创建仪表板的最常用方法。 本教程将从分析师查看网站日志的角度使用示例数据&#xff0c;但这种类型的仪表板适用于任何类型的数据。 完成后&#xff0c;你将全面了解示例 Web 日志数据。 在本次的展示中&#xff0c;我将使用最新的 Elastic Stack 8.7.1 来…

百分比图:解读数据,驱动业务增长

在当今信息爆炸的时代&#xff0c;数据成为了各行各业决策的重要依据。而在数据展示的众多形式中&#xff0c;百分比图凭借其简洁直观的表达方式和强大的信息传递能力&#xff0c;成为了企业和组织不可或缺的工具。本文将带您一同探索百分比图的魅力&#xff0c;揭示其在决策智…

介绍一下全链路压测平台的相关内容

随着互联网技术的不断发展&#xff0c;越来越多的企业开始依赖互联网来实现业务的发展和增长。而对于这些企业而言&#xff0c;如何保证他们的业务在高并发、高负载的情况下依然能够正常运行&#xff0c;是非常重要的一个问题。为了解决这个问题&#xff0c;企业可以使用全链路…

Vue3+ElementPlus报错集锦

目录 1、导入TS类型报错 2、使用类型报错 3、Vue3引入文件爆红且不提示 4、为defineAsyncComponent引入的component子组件设置类型 1、导入TS类型报错 &#xff08;1&#xff09;报错信息 import type { FormInstance, FormRules } from element-plus 模块 ""e…

精彩回顾 | Fortinet Accelerate 2023·中国区巡展杭州站

Fortinet Accelerate 2023中国区巡展 5月18日&#xff0c;Fortinet Accelerate 2023中国区巡展来到杭州&#xff0c;Fortinet携手太平洋电信、亚马逊云科技等云、网、安合作伙伴&#xff0c;与各行业典型代表客户&#xff0c;就网安融合、网安协同、工业互联网安全、云安全、网…

LC-1080. 根到叶路径上的不足节点(递归DFS)

1080. 根到叶路径上的不足节点 难度中等126 给你二叉树的根节点 root 和一个整数 limit &#xff0c;请你同时删除树中所有 不足节点 &#xff0c;并返回最终二叉树的根节点。 假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit&#xff0c;则该…

网络安全有什么学习误区?

一、网络安全学习的误区 1.不要试图以编程为基础去学习网络安全 不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;且过渡到网络安全用到编程的用到的编程的关键点不多。一般人如果想要把编程学好再开始学习网络安全往…

【STM32系列】基础操作及LED测试

【STM32系列】基础操作及LED测试 资源常用网站整理基本操作恢复出厂设置 欢迎收看由咸鱼菌工作室出品的STM32系列教程。本篇内容主要是开发板的基础操作 资源 首先给大家推荐一些学习micropython的资源网站&#xff0c;文字版直接去我的博客里面翻一下 以下是一些Micropyth…

redis问题汇总

redis的优点 读写性能优异。十万/s的量级&#xff1b; 支持数据持久化。AOF,RDB 支持丰富的数据类型&#xff1b; 支持集群&#xff0c;可以实现主从复制&#xff0c;哨兵机制迁移&#xff0c;扩容等 缺点&#xff1a; 因为是基于内存的&#xff0c;所以虽然redis本身有key过期…

单片机如何通过PWM脉冲控制电机转速?

通过单片机实现对电机自动化控制已经在各行各业得到广泛应用&#xff0c;电机转速灵活使用方便&#xff0c;控制性能好&#xff0c;易于大范围调速。单片机通过PWM脉冲控制电机转速&#xff0c;在现代化生产中起到重要作用。 单片机是一种集成电路芯片&#xff0c;包括处理器、…