[数据结构1.0]选择排序

news2024/12/29 7:40:05

鼠鼠前面的博客介绍过选择排序是常见的排序算法,选择排序有但不限于直接选择排序和堆排序!那么鼠鼠今天浅谈一下选择排序!

鼠鼠本博客用排升序来介绍选择排序!

目录

1.直接选择排序

1.1.直接选择排序

 1.2.直接选择排序特性

2.堆排序

2.1.堆排序

2.2.堆排序特性

3.效率比较


选择排序的基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

1.直接选择排序

1.1.直接选择排序

1.在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素。

2.若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换。

3.在剩余的array[i]到array[n-2](array[i+1]到array[n-1])集合中,重复上述步骤,直到集合剩余1个元素。

其实说简单点,拿排升序来说:“单趟” 就是遍历需要排序的乱序数组找出最小的数据与第一个数据交换。循环”多趟“在剩余的数据集合中找最小的数据与剩余数据集合的第一个数据交换,直到剩余数据集合数为1停止。

思想很简单,就算鼠鼠解释的不好,相信读者老爷也能明白的,看代码:

1.”单趟“代码(不是直接选择排序完整代码)

int i = begin;
		int mini = i;
		while (i <= end)
		{
			if (a[mini] > a[i])
			{
				mini = i;
			}
			i++;
		}
		Swap(&a[mini], &a[begin]);

2.循环控制好begin就能很好控制好数据集合范围,直接选择排序完整代码如下:

void SelectSort(int* a, int begin, int end)
{
	while (begin < end)
	{
		int i = begin;
		int mini = i;
		while (i <= end)
		{
			if (a[mini] > a[i])
			{
				mini = i;
			}
			i++;
		}
		Swap(&a[mini], &a[begin]);
		begin++;
	}
}

我们拉出来试试能不能排好:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void SelectSort(int* a, int begin, int end)
{
	while (begin < end)
	{
		int i = begin;
		int mini = i;
		while (i <= end)
		{
			if (a[mini] > a[i])
			{
				mini = i;
			}
			i++;
		}
		Swap(&a[mini], &a[begin]);
		begin++;
	}
}

void PrintArrar(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");
}

int main()
{
	int a[] = { 7,5,6,1,3,4,2,2 };
	PrintArrar(a, sizeof(a) / sizeof(a[0]));
	SelectSort(a, 0, sizeof(a) / sizeof(a[0]) - 1);
	PrintArrar(a, sizeof(a) / sizeof(a[0]));
	return 0;
}

 没啥问题!

 1.2.直接选择排序特性

 1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用。

2. 时间复杂度很明显是O(N^2)。

3. 空间复杂度很明显是O(1)。

2.堆排序

2.1.堆排序

堆排序鼠鼠之前浅浅介绍过了,这篇博客介绍过,这里就不介绍了。唯一要注意:排升序要建大堆,排降序建小堆。

我们用堆排序排个升序看看:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

//向下调整(大堆)
void AdjustDown(int* a, int parentcoordinate, int HeapSize)
{
	int childcoordinate = parentcoordinate * 2 + 1;
	while (childcoordinate < HeapSize)
	{
		if (a[childcoordinate] < a[childcoordinate + 1] && childcoordinate + 1 < HeapSize)
		{
			childcoordinate++;
		}
		if (a[parentcoordinate] < a[childcoordinate])
		{
			Swap(&a[parentcoordinate], &a[childcoordinate]);
			parentcoordinate = childcoordinate;
			childcoordinate = childcoordinate * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

//堆排序排升序
void HeapSort(int* a, int HeapSize)
{
	int i = 0;
	//排升序,建大堆(向下调整建堆法)
	for (i = (HeapSize - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, i, HeapSize);
	}
	int end = HeapSize - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, 0, end);
		end--;
	}
}

int main()
{
	int a[] = { 90,80,60,20,40,70,60,30,30,110 };
	int Size = sizeof(a) / sizeof(a[0]);
	printf("堆排序前:");
	for (int i = 0; i < Size; i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n");

	HeapSort(a, Size);
	printf("堆排序后:");
	for (int i = 0; i < Size; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

 确实排好了!

2.2.堆排序特性

1. 堆排序使用堆来选数,效率就高了很多。

2. 时间复杂度:O(N*logN)。

3. 空间复杂度:O(1)。

3.效率比较

鼠鼠用这两排序来排10w个相同的随机数,大致能看出效率差距:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

void Swap(int* a, int* b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

//直接选择排序
void SelectSort(int* a, int begin, int end)
{
	while (begin < end)
	{
		int i = begin;
		int mini = i;
		while (i <= end)
		{
			if (a[mini] > a[i])
			{
				mini = i;
			}
			i++;
		}
		Swap(&a[mini], &a[begin]);
		begin++;
	}
}

//向下调整(大堆)
void AdjustDown(int* a, int parentcoordinate, int HeapSize)
{
	int childcoordinate = parentcoordinate * 2 + 1;
	while (childcoordinate < HeapSize)
	{
		if (a[childcoordinate] < a[childcoordinate + 1] && childcoordinate + 1 < HeapSize)
		{
			childcoordinate++;
		}
		if (a[parentcoordinate] < a[childcoordinate])
		{
			Swap(&a[parentcoordinate], &a[childcoordinate]);
			parentcoordinate = childcoordinate;
			childcoordinate = childcoordinate * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//堆排序排升序
void HeapSort(int* a, int HeapSize)
{
	int i = 0;
	//排升序,建大堆(向下调整建堆法)
	for (i = (HeapSize - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, i, HeapSize);
	}
	int end = HeapSize - 1;
	while (end > 0)
	{
		Swap(&a[0], &a[end]);
		AdjustDown(a, 0, end);
		end--;
	}
}

int main()
{
	int n = 100000;
	int* a = (int*)malloc(sizeof(int) * n);
	int* b = (int*)malloc(sizeof(int) * n);
	srand((unsigned int)time(0));
	for (int i = 0; i < n; i++)
	{
		a[i] = rand() + i;
		b[i] = a[i];
	}
	int begin1 = clock();
	SelectSort(a, 0, n - 1);
	int end1 = clock();
	printf("SeleckSort:%d\n", end1 - begin1);
	int begin2 = clock();
	HeapSort(a, n);
	int end2 = clock();
	printf("HeapSort:%d\n", end2 - begin2);
	return 0;
}

我们可以看到在Debug版本下结果:

 感谢阅读!

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

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

相关文章

【qt】动态属性

这里写目录标题 一.属性1.属性的好处2.添加属性3.使用属性 二.只读属性 一.属性 1.属性的好处 说到属性&#xff08;property&#xff09;&#xff0c;你们会想到什么&#xff1f;我会联想到特点&#xff0c;就是一类对象所特有的&#xff0c;在C中&#xff0c;成员数据就是这…

标准流、浮动、flex布局

标准流 浮动 特点&#xff1a; 具备顶对齐&#xff0c;行内块显示特点&#xff0c;浮动的盒子是脱离了标准流。 如果父级的宽度不够&#xff0c;浮动的盒子会掉下来 <style>.one{width: 200px;height: 200px;background-color: aqua;float: left;}.two{width: 200px;he…

zabbix监控mariadb

zabbix 服务端安装请参阅&#xff1a;红帽 9 zabbix 安装流程_红帽安装zabbix-CSDN博客 源码包安装mariadb请参阅&#xff1a;源码包安装mariadb_mariadb 11 源码编译安装-CSDN博客 在MariaDB中&#xff0c;你需要创建一个专门的用户&#xff0c;用于Zabbix进行监控。这个用户…

PingCAP 戴涛:构建面向未来的金融核心系统

作者&#xff1a;戴涛 导读 近日&#xff0c;平凯星辰解决方案技术部总经理戴涛在 2024 数据技术嘉年华活动中&#xff0c;做了主题为“构建面向未来的金融核心系统”的分享&#xff0c;本文为戴涛演讲实录的全文。 文章分析了中国金融行业的发展趋势&#xff0c;并且基于这…

Typescript 哲学 - ts模块使用最佳实践

ts的作用域 默认是全局&#xff08;global&#xff09;&#xff0c;这也是为什么在 两个ts文件声明同一个变量报错变量名冲突&#xff0c;解决方法是使某个文件以模块的形式存在&#xff08;文件顶层使用 export 、import &#xff09; In TypeScript, just as in ECMAScript 2…

微软如何打造数字零售力航母系列科普10 - 什么是Azure Databricks?

什么是Azure Databricks&#xff1f; 目录 一、数据智能平台是如何工作的&#xff1f; 二、Azure Databricks的用途是什么&#xff1f; 三、与开源的托管集成 四、工具和程序访问 五、Azure Databricks如何与Azure协同工作&#xff1f; 六、Azure Databricks的常见用例是…

2024.5组队学习——MetaGPT智能体理论与实战(待续)

学习资料&#xff1a;项目地址——hugging-multi-agent、在线阅读、MetaGPT项目、MetaGPT中文文档 文章目录 一、环境配置1.1 配置MetaGPT1.2 配置大模型api_key1.3 测试demo 一、环境配置 全部工作在Autodl上完成&#xff0c;下面是简单记录&#xff1a; 1.1 配置MetaGPT 下…

Android Activity因配置改变重建,ViewModel#onClear方法为什么不被调用?

1&#xff0c;问题 注意到切换语言或字体大小改变时&#xff0c;Activity会发生重建&#xff0c;但对应的ViewModel却不会被clear&#xff0c;甚至在重建的Activity&#xff0c;通过new ViewModelProvider(this).get(ViewModel.class)也是上一个Activity的实例&#xff0c;为什…

【精读Yamamoto】方向性连接如何丰富神经网络的功能复杂度 | 体外神经元培养实验 | 脉冲神经元模型(SNN) | 状态转移模型

探索大脑的微观世界&#xff1a;方向性连接如何丰富神经网络的功能复杂度 在神经科学领域&#xff0c;理解大脑如何通过其复杂的网络结构实现高级功能一直是一个核心议题。最近&#xff0c;一项由Nobuaki Monma和Hideaki Yamamoto博士领导的研究为我们提供了新的视角&#xff…

Linux----正则表达式练习题题解

1、 显示/etc/rc.d/rc.sysinit文件中以不区分大小的h开头的行&#xff1b; [rootopenEuler ~]# grep -E "^(H|h)" /etc/passwd halt:x:7:0:halt:/sbin:/sbin/halt 注&#xff1a;当然也可以使用grep -i来实现&#xff0c;这里我换了一个文件&#xff08;/etc/passw…

第240513章 消除Otostudio关于库文件的48个报警

第240513章 消除Otostudio关于库文件的48个报警 文章目录 第240513章 消除Otostudio关于库文件的48个报警前言一、替换Lib_Googol文件夹二、替换扩展模块配置文件三、复制MODBUSTCP库到Lib_Googol文件夹四、替换GTS800和DEFAULT文件五、仿真模拟 前言 一、替换Lib_Googol文件夹…

ARM架构安全特性之通用平台安全服务

安全之安全(security)博客目录导读 目录 一、符合PSA认证标准 二、Arm平台安全规范 三、跨安全边界通信 四、FF-A 五、FF-M 六、开放和标准设备固件 七、Trustedfirmware.org 在一个需要高度信任设备的世界中&#xff0c;每个设备都必须是独一无二的可识别的、不可克隆…

AI“源神”启动!Llama 3发布,开闭源之争战局生变

在AI的世界里&#xff0c;开源与闭源的较量一直是科技界的热门话题。 今年年初&#xff0c;埃隆马斯克在对OpenAI及其CEO萨姆奥特曼提起诉讼时&#xff0c;就对OpenAI逐渐不公开其模型研究相关细节的行为大加谴责。“时至今日&#xff0c;OpenAI公司网站还宣称&#xff0c;它的…

新的语言学习系统: 记忆镶嵌

摘要 记忆镶嵌是由多个关联记忆网络协同工作来完成感兴趣的预测任务。与transformer类似,记忆镶嵌具有组合能力和上下文学习能力。与transformer不同,记忆镶嵌以相对透明的方式实现这些能力。该研究在玩具示例上展示了这些能力,并且还表明记忆镶嵌在中等规模语言建模任务上的表…

PCIE协议-2-事务层规范-Message Request Rules-Vendor_Defined Messages

2.2.8.6 厂商定义消息 厂商定义消息允许扩展PCI Express消息功能&#xff0c;可以作为PCI Express规范的一般扩展&#xff0c;也可以是厂商特定的扩展。本节通用地定义了与这些消息相关的规则。 厂商定义消息&#xff08;见表2-25&#xff09;使用图2-28中显示的头标格式。re…

栈队列经典OJ题(详细过程)

1. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 第一题判断有效的括号&#xff0c;这道题我们会用到栈的知识&#xff0c;栈是后进先出的&#xff0c;可以根据这个来解这道题&#xff0c;先看一下题目和示例。 1.1整体思路 我们通过示例可以看出括号匹配就返回true&am…

【STM32 |示例程序】EXTI中断示例程序(对射式红外传感器旋转编码器计次)

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; 丠丠64-CSDN博客&#x1f388;&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起…

MinIO学习笔记

MINIO干什么用的&#xff1a; AI数据基础设施的对象存储 为人工智能系统提供数据支持&#xff0c;数据存储&#xff1b;对象存储&#xff08;Object Storage&#xff09;是一种数据存储架构&#xff0c;它以对象为单位来处理、存储和检索数据&#xff0c;每个对象都包含了数据本…

Maven、JavaWeb基础开发

1 Maven介绍 1、标准化的项目结构 2、标准化的构建流程 3、依赖管理 4、依赖范围 2 JavaWeb基础开发 2.1 Http协议 1 Http请求数据格式 2 Http响应数据格式 2.2 Web服务器&#xff08;Tomcat&#xff09; VTS、FileServer使用Tomcat部署&#xff1b; 其他服务单元TESLA S…

前端使用Compressor.js实现图片压缩上传

前端使用Compressor.js实现图片压缩上传 Compressor.js官方文档 安装 npm install compressorjs使用 在使用ElementUI或者其他UI框架的上传组件时&#xff0c;都会有上传之前的钩子函数&#xff0c;在这个函数中可以拿到原始file&#xff0c;这里我用VantUI的上传做演示 a…