【选择排序】直接选择排序 与 堆排序

news/2024/5/19 5:47:33 标签: 排序算法, 数据结构, 算法, c语言, 堆排序

目录

1. 排序的概念:

2.选择排序的基本思想

3.直接选择排序

4.堆排序


1. 排序的概念:

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种算法>排序算法是稳定的;否则称为不稳定。

内部排序:数据元素全部放在内存中的排序。

外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。

2.选择排序的基本思想

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

3.直接选择排序

  • 在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素
  • 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换。
  • 在剩余的array[i]--array[n-2] (array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

选择排序图解:这张动图是选择后面最小的数与前面做交换

当让我们还可以优化,如果是升序,每一次遍历分别选出最小的元素和最大的元素,分别与前面和后面数据做交换。

代码实现:

//交换函数
void Swap(int* p1, int* p2)
{
	int t = *p1;
	*p1 = *p2;
	*p2 = t;
}

// 选择排序 升序
void SelectSort(int* arr, int n)
{
	int begin = 0;
	int end = n - 1;
	while (begin < end)
	{
		int maxi = begin;
		int mini = begin;
		for (int i = begin; i <= end; i++)
		{
			if (arr[i] > arr[maxi])
			{
				maxi = i;
			}
			if (arr[i] < arr[mini])
			{
				mini = i;
			}
		}
		Swap(&arr[mini], &arr[begin]);
		if (begin == maxi)
		{
			maxi = mini;
		}
		Swap(&arr[maxi], &arr[end]);
		begin++;
		end--;
	}
}

直接选择排序的特性总结:

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

4.堆排序

我们这里需要先了解堆的结构,如果不了解可以看我之前的文章【数据结构】这堆是什么。

当我们了解完堆的结构后,我们就可以开始学习堆排序了。 

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

  1. 首先要构建一个堆,
  2. 然后让堆顶元素与最后一个元素交换,把最后一个位置元素当作不在堆内。
  3. 然后通过向下调整法调整堆。循环就可以排序

图解:

 建堆可以使用向上调整法建堆和向下调整法建堆,这两种方法在【数据结构】这堆是什么 中有详细讲解。向上调整法建堆时间复杂度为O(N*logN),但是向下调整法时间复杂度低,为O(N)。所以我们这里使用向下调整法建堆。

代码实现:

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

堆排序的特性总结:

  1. 堆排序使用堆来选数,效率就高了很多。
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(1)
  4. 稳定性:不稳定

本篇文章结束,我们下一篇文章来学习一下:【交换排序】冒泡排序与快速排序。


http://www.niftyadmin.cn/n/4929962.html

相关文章

KDD 2023 | 美团技术团队精选论文解读

本文精选了美团技术团队被KDD 2023收录的7篇论文进行解读&#xff0c;论文覆盖了Feed流推荐、多模态数据、实例分割、用户意图预测等多个方向。这些论文也是美团技术团队与国内多所高校、科研机构合作的成果。希望给从事相关研究工作的同学带来一些启发或者帮助。 ACM SIGKDD&a…

serverless 是什么意思

目录 1. serverless 是什么意思1.1. serverless 的含义1.2. serverless 的价值1.3. 什么是 BaaS1.4. 什么是 FaaS? 1. serverless 是什么意思 1.1. serverless 的含义 狭义 Serverless 是指: Serverless computing 架构 FaaS 架构 Trigger(事件驱动)FaaS(Function as a Se…

“海纳“二维码生成器(绿色版本,离线无需安装)

介绍一款所见即所得的二维码生成器&#xff1a;"海纳"二维码生成器&#xff0c;免费、离线&#xff0c;简单、快捷。 主要功能&#xff1a; 图形界面&#xff0c;所见即所得&#xff1b;支持数字、字符、汉字等生成二维码&#xff1b;支持网址、邮件地址&#xff1…

springboot开发的悠点装饰后台管理系统java公司装修设计jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 springboot开发的悠点装饰后台管理系统 系统有1权限&…

【nginx】配置将HTTPS请求转换成HTTP

要将HTTPS请求转换为HTTP请求&#xff0c;可以在Nginx的配置文件中添加以下配置&#xff1a; 打开Nginx的配置文件&#xff0c;通常位于/etc/nginx/nginx.conf或/etc/nginx/conf.d/default.conf。 在server块中添加以下配置&#xff0c;将HTTPS请求转发到后端的HTTP服务&#…

在SockJS+Spring Websocket中convertAndSendToUser中的“用户”来自哪里?

目录 一、前言二、Principal三、使用 一、前言 我们知道可以使用客户端订阅的主题前缀从 stomp 服务器向客户端发送消息&#xff0c;例如 /topic/hello。我们还知道我们可以向特定用户发送消息&#xff0c;因为 spring 提供了convertAndSendToUser(username, destination, mes…

互联网黑话缩写

文章目录 黑话缩写及含义 黑话缩写及含义 写在最前面 ——————我是分界线—————— 从去年实习到刚刚入职一个月&#xff0c;作为职场小白的我&#xff0c;时常从导师或者同事口中听到各种77怪怪陌生的黑话缩写&#xff0c;包括技术黑话&#xff0c;也包括职位黑话&…

Element组件浅尝辄止5:Empty 空状态组件

Empty空状态组件&#xff1a;空状态时的占位提示。 如第一次进入当前功能模块时&#xff0c;数据状态为空&#xff0c;则展示空状态&#xff0c;可用到Empty组件 1.How? <el-empty description"描述文字"></el-empty> 2.自定义图片 通过设置 image 属…