【数据结构】直接插入排序,希尔排序,选择排序,堆排序

news2024/12/22 19:55:20

文章目录

  • 排序的概念
  • 直接插入排序
  • 希尔排序
  • 选择排序
  • 堆排序

排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次
序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排
序算法是稳定的;否则称为不稳定的。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

直接插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
实际中我们玩扑克牌时,就用了插入排序的思想
在这里插入图片描述
当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移.。请添加图片描述

void InsrtSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int end=i;
		int tmp = a[end + 1];
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				break;
			}
		}
		a[end+1] = tmp;
	}
}

直接插入排序的特性总结

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1),它是一种稳定的排序算法
  4. 稳定性:稳定
    稳定性在排序的概念当中也是介绍到了·,具体就是例如数组当中有两个相同的数,在排完序之后两个数的前后关系是没有变的,这就属于稳定,如果变了就是不稳定。

希尔排序

当我们学习过直接插入排序就可以发现当数组逆序时想要排序是非常麻烦的,而对于数组相对有序就会非常的友好,希尔排序就是用来解决直接插入排序的弊端。
希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工 作。当到达=1时,所有记录在统一组内排好序。
将希尔排序分为两部分:先进行预排序之后再进行直接插入排序·,当排升序时,可以理解为预排序将大的数更快的移到后面。
升序:
1.gap越大,大的数就越快得到后面,小的数也就越快的到前面,也就越不接近有序。
2.gap越小,数据跳动的越慢,越接近有序。

在这里插入图片描述

void ShellSort(int* a, int n)
{
	int gap = n;
	//gap>1预排序
	//gap==1直接插入排序
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; i++)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (tmp < a[end])
				{
					a[end + gap] = a[end];
					end-=gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化。
  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:
    因为咋们的gap是按照Knuth提出的方式取值的,而且Knuth进行了大量的试验统计,我们暂时就按照:O(N^1.3)来算。也可以从 O(N*logN)到O(N^2)
    空间复杂度:O(1)
  4. 稳定性:不稳定

选择排序

选择排序基本思想
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
选择排序:
在元素集合array[i]–array[n-1]中选择关键码最大(小)的数据元素
若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换在剩余的array[i]–array[n-2](array[i+1]–array[n-1])集合中,重复上述步骤,直到集合剩余1个元素。
选择排序与直接插入排序好坏
相比之下插入排序更好,当数据处于有序或者接近有序的情况下,效率会得到提升。
他的适应性更强。
而选择排序任何情况下都是O(N^2)。
请添加图片描述

void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	while (end > begin)
	{
		int mini = begin;
		int maxi = begin;
		for (int i = begin + 1; i <= end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}
			if (a[i] > a[maxi])
			{
				maxi = i;
			}
		}
		swap(&a[begin],&a[mini]);
		if (maxi == begin)
		{
			maxi = mini;
		}
		swap(&a[end],&a[maxi]);
		begin++;
		end--;
	}
}

选择排序的特性总结

  1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。

void AdjustDown(int* a, int n, int parent)
{
	int child = parent * 2 + 1;
	while (child < n)
	{
		// 确认child指向大的那个孩子
		if (child + 1 < n && a[child + 1] > a[child])
		{
			++child;
		}
		// 1、孩子大于父亲,交换,继续向下调整
		// 2、孩子小于父亲,则调整结束
		if (a[child] > a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

// O(N*logN)
void HeapSort(int* a, int n)
{
	// 向下调整建堆 -- O(N)
	// 升序:建大堆
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
		AdjustDown(a, n, i);
	}

	// O(N*logN)
	int end = n - 1;
	while (end > 0)
	{
		swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		--end;
	}
}

堆排序排序的特性总结

  1. 堆排序使用堆来选数,效率就高了很多。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定
最后:文章有什么不对的地方或者有什么更好的写法欢迎大家在评论区指出

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

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

相关文章

keras环境搭建

目录 1. 安装miniconda 2. 安装CPU版本的tensorflow 2. 安装keras 3. 安装依赖库 4. 测试 环境&#xff1a;win10&#xff0c;无独立显卡&#xff0c;不用GPU加速。 1. 安装miniconda Miniconda3-latest-Windows-x86_64.exe &#xff08;1&#xff09;安装目录可自选&a…

生成对抗:Pix2Pix

cGAN : Pix2Pix 生成对抗网络还有一个有趣的应用就是&#xff0c;图像到图像的翻译。例如:草图到照片&#xff0c;黑白图像到RGB&#xff0c;谷歌地图到卫星视图&#xff0c;等等。Pix2Pix就是实现图像转换的生成对抗模型&#xff0c;但是Pix2Pix中的对抗网络又不同于普通的GAN…

计网第三章.数据链路层—可靠传输

以下来自湖科大计算机网络公开课的笔记 文章目录0.基本概念1. 停止等待协议SW2. 回退N帧协议GBN3. 选择重传SR首先&#xff0c;这部分说的可靠传输的实现机制不只限于数据链路层&#xff0c;而是适用于整个计算机网络体系 0.基本概念 一般情况下&#xff0c;有线链路的误码率…

Docker 中的挂载卷

我们现在有这样一个需求。 我们有一个 Spring 的项目是部署在容器中的&#xff0c;如果不进行任何配置的话&#xff0c;这个项目运行的所有日子都会在容器中。 当容器重启说着终止后&#xff0c;上面的日志比较难进行查看。 我们希望我们的日志同时也记录在操作系统中&#…

阿贡国家实验室:量子中继器及其在量子网络中的作用

很多人小时候都玩过传声筒游戏&#xff1a;A将消息小声告诉B&#xff0c;然后B将他听到的内容小声告诉C&#xff0c;依此类推&#xff0c;玩过的人都知道&#xff0c;最后传达到的信息往往和真实消息完全不同。 从某种意义上说&#xff0c;这和中继器技术的重要性强相关。中继器…

MySQL锁,锁的到底是什么?

只要学计算机&#xff0c;「锁」永远是一个绕不过的话题。MySQL锁也是一样。 一句话解释MySQL锁&#xff1a; MySQL锁是解决资源竞争的一种方案。 短短一句话却包含了3点值得我们注意的事情&#xff1a; 对什么资源进行竞争&#xff1f;竞争的方式&#xff08;或者说情形&a…

舆情监控和应急处理方案,如何做好网络舆情监控?

舆情监控是指通过不同的渠道&#xff0c;如社交媒体、新闻媒体、博客、论坛等&#xff0c;对公众的言论进行收集、分析、评估和反馈的过程。舆情监控的目的是帮助企业或组织了解公众的观点和情绪&#xff0c;并且能够及时做出回应&#xff0c;避免可能出现的舆论危机。接下来TO…

2022年度投影仪行业数据分析报告:十大热门品牌排行榜

在当前的大环境下&#xff0c;线下娱乐受阻&#xff0c;而用户对于足不出户的观影、娱乐需求推动着智能投影设备的增长。近几年来&#xff0c;投影仪行业保持着较快速度的增长&#xff0c;面对整体市场需求不振的形势&#xff0c;投影仪仍在保持正向增长。随着家用智能投影在市…

Charles - 阻塞请求、修改请求与响应内容、重定向请求地址、指定文件为响应内容

1、阻塞请求 1、鼠标放在指定接口上 > 右键 > 勾选 Block List 2、重新访问这接口&#xff0c;这条请求被阻塞&#xff0c;不会有返回信息 取消阻塞接口&#xff1a; 鼠标放在指定接口上 > 右键 > 取消勾选 Block List 2、修改请求与响应内容 第一步&#xff1…

【一文看懂 ES 核心】存储查询集群

一文看懂 ES 核心 Elasticsearch 作为一个搜索引擎&#xff0c;其可以提供高效的搜索匹配数据的能力&#xff0c;对于这类工具了解其运行原理其实是有一套功法的。 聊存储&#xff0c;ES 是如何存储数据的&#xff1f;聊方法&#xff0c;ES 是如何进行搜索匹配的&#xff1f;…

【Linux】文件描述符、文件操作、重定向的模拟实习

目录 一、重温C语言文件操作 1.1 文件打开方式 1.2 文件写操作 1.3 文件读操作 1.3 标准输入输出 二、系统接口的使用 2.1 open 函数 2.2 close 函数 2.3 write 函数 2.4 read 函数 三、文件描述符 3.1 如何管理文件 3.2 0 & 1 & 2 3.3 文件描述符的分配…

种草!超好用的PDF转换器上线啦~

宝子们 重磅福利来啦 你还在为每次转换文件头疼吗 老铁&#xff0c;大拿版万能转换器正式上线啦 以前的文件转换器&#xff0c;不是充会员就是收费高 最坑的是花钱还解决不了问题 每次转换文件内容有误.... 特殊符号或者公式更是无法有效转换 为了整顿这种局面&#xff0c…

KKT条件理解

我们知道拉格朗日函数是用于等式约束的优化问题求解的&#xff0c;然KKT条件是针对含有不等式约束的优化问题的。 首先&#xff0c;我们先给出优化目标&#xff1a; 因此&#xff0c;根据优化目标&#xff0c;我们同样可以构造处拉格朗日函数&#xff0c;并对其进行优化&#…

ssh免密登录

准备两台linux主机 主机A&#xff1a;192.168.92.131 主机B&#xff1a;192.168.92.132 使用主机B去免密访问主机A 在主机B上执行 ssh-keygen -t rsa ssh-keygen 生成密码对 -t rsa 指定生成 rsa 密钥对 密钥对文件默认放在 家目录下面的 .ssh 目录下 root 用户默认放在 /ro…

一、数据库开发与实战专栏导学及数据库基础概念入门

文章目录一、专栏导学1.1 课程内容1.2 学习安排1.3 适合人群1.4 学习方法二、认识数据库2.1 生活中的数据库2.2 数据管理技术的3个发展阶段2.3 数据库、关系型数据库、非关系型数据库概念2.4 为什么要使用数据库2.5 数据库系统及其组成部分2.6 常用数据库访问接口简介2.7 数据库…

【2】Go语言的语法

一、Go语言基础组成 Go语言基础组成&#xff1a; 包申明引入包函数变量语句&表达式注释实例&#xff1a; package main //申明包 import "fmt" /* 这是一个朴实无华的注释 */ func main() { fmt.Printf("mogu") } 实现流程&#xff1a; 第一行&#…

kafka简介

目录 partition和consumer group offset的管理 kafka的事务 幂等producer 事务producer 怎么理解trasactional.id 两阶段2pc简介 kafka的消息传输保证 producer端 broker端 consumer端 消息挤压 kafak的存储 kafka的高性能 附录-kafka demo kafaka的发布-订阅模…

Rust之常用集合(三):哈希映射(Hash Map)

开发环境 Windows 10Rust 1.66.0VS Code 1.74.2项目工程 这里继续沿用上次工程rust-demo 在哈希图中存储带有关联值的键 我们常见的集合中的最后一个是哈希映射。HashMap<K, V>类型使用散列函数存储K类型的键到V类型的值的映射&#xff0c;这决定了它如何将这些键和值…

Vue2.0

JavaScript&#xff08;JS 教程&#xff09; - JavaScript | MDN Vue是构建用户界面的 JavaScript 框架 安装 — 2.0 Vue.jsGitHub - vuejs/devtools: ⚙️ Browser devtools extension for debugging Vue.js applications.Installation | Vue DevtoolsVSCode插件&#xff1a…

【SpringMVC】SpringMVC整合Mybatis

1.整合思路 第一步&#xff1a;整合dao层 mybatis和spring整合&#xff0c;通过spring管理mapper接口使用mapper的扫描自动扫描mapper接口在spring中进行注册 第二步&#xff1a;整合service层 通过spring管理service接口使用配置方式将service接口配置在spring配置文件中实现…