选择排序与堆排序

news/2024/5/20 6:57:41 标签: 排序算法, 算法, 数据结构, c语言,

全文目录

  • 引言
  • 选择排序
    • 思路
    • 实现
  • 排序
    • 思路
    • 实现
  • 总结

引言

从这篇文章开始,将介绍几大算法>排序算法:选择排序、排序、直接插入排序、希尔排序、冒泡排序、快速排序、归并排序以及计数排序。

在本篇文章中要介绍的是选择排序与排序,它们都属于选择排序。
这两种算法>排序算法的思想都是从待排序的数据元素中选出最大或最小的元素,放在序列的起始位置或末尾位置,以此来使整个序列有序:

选择排序

思路

选择排序就很符合上面的描述:从数组中选出最小的元素,放在数组的起始位置。然后就相当于起始位置的元素就是正确的位置,也就相当于需要排序的部分减少了一个元素。由此循环就可以实现排序整个数组:

实现

这样的思路,很明显是需要两层循环的:
内层循环需要确定出当前待排序部分中最小的元素,并将其下标记录下来。每次内层循环后,将最小元素与待排徐部分的起始元素交换;
外层循环需要缩小待排序部分的大小。从数组的大小开始,直到待排序部分为0,即整个数组排序完毕:

在这里插入图片描述

void Swap(int* a, int m, int n)//交换
{
	int temp = a[n];
	a[n] = a[m];
	a[m] = temp;
}
//选择排序
void SelectSort(int* a, int n)
{
	for (int i = 0; i < n - 1; i++)
	{
		int min = a[i];
		int mini = i;
		for (int j = i + 1; j < n; j++)
		{
			if (a[j] < min)
			{
				min = a[j];
				mini = j;
			}
		}
		Swap(a, i, mini);
	}
}

排序

思路

排序是建立在二叉树上的一种排序方法,在前面我们详细介绍了二叉树与这种数据结构
对于大而言,顶的元素是该中最大的元素。我们只需要通过不断建,不断将顶的元素放到当前待排序的部分的末尾。就相当于末尾元素就在其正确的位置。逐渐缩小的大小就可以实现排序整个数组。

实现

在这个思路下,我们需要两次循环:

第一次循环实现将当前数组所有元素建大
时,有两种方式:向上调整建与向下调整建
向上调整建时,类似于二叉树的尾插,然后将这个尾插的数向上调整放到合适的位置;
向下调整建时,即将每一个根结点向下调整,放在其合适的位置。这要求该根的子树都是正确的大,所以我们需要从倒数第二层的根结点开始向下调整:
(向下调整建的时间复杂度是比向上调整少的,在这里不做证明,在本篇文章中也只实现向下调整建
在这里插入图片描述
第二次循环需要实现不断将顶的元素与当前待排序部分所建的末尾元素交换,使该元素完成排序。然后待排序的部分缩小,待排序部分再次建大。直到排序结束:

(关于向下调整的AdjustDown函数,在中有详细讲解,这里就不赘述:戳我看及其实现详解)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void Swap(int* a, int m, int n)//交换
{
	int temp = a[n];
	a[n] = a[m];
	a[m] = temp;
}
void AdjustDwon(int* a, int n, int root)//向下调整建
{
	int parent = root;
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child + 1] > a[child])
		{
			child++;
		}
		if (a[child] > a[parent])
		{
			Swap(a, child, parent);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
//排序
void HeapSort(int* a, int n)
{
	for (int i = (n - 2) / 2; i >= 0; i--)//建
	{
		AdjustDwon(a, n, i);
	}
	for (int i = 1; i < n ; i++)//排序
	{
		Swap(a, 0, n-i);
		AdjustDwon(a, n - i, 0);
	}
}

总结

到此,关于选择排序与排序的内容就介绍完了
接下来会继续介绍其他的排序,欢迎持续关注哦

如果大家认为我对某一部分没有介绍清楚或者某一部分出了问题,欢迎大家在评论区提出

如果本文对你有帮助,希望一键三连哦

希望与大家共同进步哦


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

相关文章

ChatGPT 速通手册——ChatGPT 的极简理解

Stephen Wolfram 写了一篇文章&#xff0c;深入浅出的介绍了 ChatGPT 的原理。不过对于本书的读者&#xff0c;或者说 ChatGPT 的使用者们而言&#xff0c;是否掌握 Transformer、BERT、GPT、zero-shot、InstructGPT 的原理&#xff0c;并不影响我们基于 ChatGPT 技术进行实际运…

随想录Day55--动态规划: 392.判断子序列 , 115.不同的子序列

392.判断子序列 思路 &#xff08;这道题也可以用双指针的思路来实现&#xff0c;时间复杂度也是O(n)&#xff09; 动态规划五部曲分析如下&#xff1a; 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c;和…

Glang语言基础

语法基础 因为Go官方建议使用最新稳定版本&#xff0c;很多库也是这样做的。我们教学也采用最新稳定版&#xff0c;本次使用Go 1.18.x版本。注释 // 单行注释 /* xxxx */ 编译器忽略该区间&#xff0c;其间都被认为是注释内容。虽然Go支持&#xff0c;但很少使用// 这是包注…

理解unsafe-assume-no-moving-gc包

1. 背景在之前的《Go与神经网络&#xff1a;张量计算》[1]一文中&#xff0c;不知道大家是否发现了&#xff0c;所有例子代码执行时&#xff0c;前面都加了一个环境变量ASSUME_NO_MOVING_GC_UNSAFE_RISK_IT_WITH&#xff0c;就像下面这样&#xff1a;$ASSUME_NO_MOVING_GC_UNSA…

微服务架构第一章:centOS7.9搭建nacos集群详解

1.虚拟机安装mysql5.6 &#xff08;亲测不必非得安装mysql8&#xff09;mysq一定要开远程访问权限 centOS安装mysql5.6教程 2.官网下载nacos稳定版2.1.1 按照官方文档进行安装即可 其实就是下载源码包zip或者tar.gz解压即可 nacos官方api 配置java环境变量 vi /etc/profi…

【C++11】右值引用和移动语义

目录 右值引用和移动语义 1.1 左值引用和右值引用 1.1.1 左值和左值引用 1.1.2 右值和右值引用 1.2 左值引用与右值引用比较 1.3 左值引用使用场景和意义 1.4 右值引用的使用场景和意义 1.5 右值引用引用左值及其一些更深入的使用场景分析 1.6 完美转发 1.6.1 万能引…

【C】Array

系列连载 【python / C / C】 参考 《C语言程序设计&#xff08;第四版&#xff09;谭浩强》【C语言】C语言视频教程《郝斌 C 语言自学教程》 文章目录为什么需要数组数组的分类一维数组二维数组多维数组#include<stdio.h>int main(){int a[5] { 1, 2, 3, 4, 5 };for…

coinex06 // 前端数据 -> ringbuffer -> cpu

目录 0. 逻辑树 1 exchange-service 发送消息 1.1 exchange-service 添加依赖 1.2. yml配置文件 1.3. Source 1.4. 配置类 1.5. 发送消息到撮合引擎 service -> impl -> EntrustOrderServiceImpl 1.6. recket-server:8080 2. match-server 接收数据 2.1 数据转…