[数据结构1.0]选择排序

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

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

目录

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版本下结果:

 感谢阅读!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FreeRTOS互斥量

目录 一、互斥量的概念 二、优先级翻转和优先级继承 1、优先级翻转 2、优先级继承 三、互斥量相关API 四、优先级实操 1、优先级翻转演示 1.1 CubeMX配置 1.2 代码实现 2、使用互斥量优化优先级翻转问题 2.1 CubeMX配置 2.2 代码实现 一、互斥量的概念 在多数情况…

数据可视化训练第6天(美国人口调查获得关于收入与教育背景的数据,并且可视化)

数据来源 https://archive.ics.uci.edu/dataset/2/adult 过程 首先&#xff1b;关于教育背景的部分翻译有问题。 本次使用字典嵌套记录数据&#xff0c;并且通过lambda在sorted内部进行对某个字典的排序&#xff0c;最后用plotly进行绘图 本次提取数据的时候&#xff0c;用到…

Cocos Creator 3.8.x 透明带滚动功能的容器

ScrollView 是一种带滚动功能的容器 1、删除ScrollView下Sprite组件的SpriteFrame 2、ScrollView下scrollBar的Sprite组件的Color设为&#xff1a;FFFFFF00 3、ScrollView下view的Graphics组件的FillColor设为&#xff1a;FFFFFF00

华火5.0台嵌式喷火电燃单灶,更懂未来生活需求

在厨电技术不断革新的今天&#xff0c;第五代华火电燃灶以其独特的技术升级和卓越性能&#xff0c;成功吸引了市场的广泛关注。作为华火品牌的最新力作&#xff0c;第五代电燃灶不仅继承了前代产品的优点&#xff0c;更在多个方面进行了显著的升级和创新。下面&#xff0c;我们…

Unity自定义动画-Animation动画数据-How is “fileIDToRecycleName“ generated

一般美术和程序分工明确的项目 fbx确实是和动画一一对应的&#xff1b; 但一些独立&#xff0c;或者小工作室的项目&#xff0c;就没法保证了&#xff0c;关键还是在于 Unity的 .meta 目录 查找和对比了一下 .fbx 和 .meta&#xff1a; 缓存和不缓存Animation 具体的Animat…

【Python】使用PyTorch训练一个手写数字识别模型(MNIST)

文章目录 1. 准备工作2. 训练网络3. 测试网络4. 训练和测试循环5. 模型保存6. 最终完整代码7. 结果截图使用PyTorch训练一个手写数字识别模型(MNIST) 在这篇博客中,使用了PyTorch构建一个简单的神经网络来识别手写数字。将使用MNIST数据集,这是一个经典的机器学习基准数据集…

电子学会C/C++编程等级考试2024年03月(一级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:倒序输出 依次输入4个整数a、b、c、d,将他们倒序输出,即依次输出d、c、b、a这4个数。 时间限制:1000 内存限制:65536 输入 一行4个整数a、b、c、d,以空格分隔。 0 < a,b,c,d < 108 输出 一行4个整数d、c、b、a,整数之间以…

白话机器学习5:卷积神经网络(CNN)原理

1.神经元 激活函数f(z)的种类&#xff1a; 2.卷积方法种类 https://mp.weixin.qq.com/s/FXzTbMG64jr93Re31Db2EA 标准卷积&#xff08;Standard Convolution&#xff09;: 特点&#xff1a;每个卷积核在输入数据的整个深度上滑动&#xff0c;计算输出特征图的一个元素。应用场…

SQL_hive的连续开窗函数

SQL三种排序&#xff08;开窗&#xff09;第几名/前几名/topN 1三种排序&#xff08;开窗&#xff09;第几名/前几名/topN思路 4种排序开窗函数 1三种排序&#xff08;开窗&#xff09;第几名/前几名/topN 求每个学生成绩第二高的科目-排序思路 t2表&#xff1a;对每个学生 的…

python数据分析——seaborn绘图1

参考资料&#xff1a;活用pandas库 matplotlib库是python的和兴绘图工具&#xff0c;而seaborn基于matplotlib创建&#xff0c;它为绘制统计图提供了更高级的接口&#xff0c;使得只用少量代码就能生成更美观、更复杂的可视化效果。 seaborn库和pandas以及其他pydata库&#xf…

防火请技术基础篇:令牌桶机制的剖析与应用

防火墙中的令牌桶机制&#xff1a;深度剖析与应用 在现代网络通信中&#xff0c;防火墙技术发挥着至关重要的作用&#xff0c;它不仅能够实现网络安全防御&#xff0c;还能通过诸如令牌桶算法等机制来有效管理网络流量&#xff0c;保证网络服务的质量。本文将全面深入地探讨防…

Vue从入门到实战Day05

一、自定义指令 自定义指令&#xff1a;自己定义的指令&#xff0c;可以封装一些dom操作&#xff0c;扩展额外功能 需求&#xff1a;当页面加载时&#xff0c;让元素将获得焦点 (autofocus在safari浏览器有兼容性) 操作dom&#xff1a;dom元素.focus() mounted() {this.$ref…

深度剖析深度神经网络(DNN):原理、实现与应用

目录 引言 一、DNN基本原理 二、DNN核心算法原理 三、DNN具体操作步骤 四、代码演示 引言 在人工智能和机器学习的浪潮中&#xff0c;深度神经网络&#xff08;Deep Neural Network&#xff0c;简称DNN&#xff09;已经成为了一种非常重要的工具。DNN模仿人脑神经网络的结…

SqlServer2016安装

1、下载 下载地址&#xff1a; https://www.microsoft.com/en-us/server-cloud/products/sql-server-2016/ 或者 MSDN, 我告诉你 - 做一个安静的工具站 开发版下载地址&#xff1a;https://myprodscussu1.app.vssubscriptions.visualstudio.com/downloads KB2919442下载地址…

【JVM基础篇】双亲委派机制介绍

文章目录 双亲委派机制简介案例&#xff1a;自底向上查找案例&#xff1a;自顶向下加载案例&#xff1a;C类在当前程序的classpath中 双亲委派机制的作用如何指定加载类的类加载器&#xff1f;面试题如果一个类重复出现在三个类加载器的加载位置&#xff0c;应该由谁来加载&…

Java入门基础学习笔记20——三元运算符、运算符优先级

1、三元运算符介绍&#xff1a; 格式&#xff1a; 条件表达式 ? 值1: 值2 执行流程&#xff1a;首先计算关系表达式的值&#xff0c;如果值为true&#xff0c;就返回值1&#xff0c;如果值为false&#xff0c;就返回值2。 例1&#xff1a; package cn.ensource.operator;p…

【数据结构】详解栈且实现

一.栈 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#xff1a;…

C--贪吃蛇

目录 前言 简单的准备工作 蛇的节点 开始前 void GameStart(pSnake ps) void WelcomeToGame() void CreateMap() void InitSnake(pSnake ps) void CreateFood(pSnake ps) 游戏进行 void GameRun(pSnake ps) int NextIsFood(pSnakeNode psn, pSnake ps) void NoFood(pSnak…

深入学习指针5,与数组和指针相关的笔试题1(C语言)

前言 Hello,亲爱的小伙伴们&#xff0c;我又来了&#xff0c;&#xff0c;今天呢我们一起来学习一下C语言关于数组和指针的部分经典题目。如果觉得不错的话不要忘了点赞&#xff0c;收藏、关注&#xff0c;你的支持就是我更新的最大动力&#xff01;&#xff01; 好&#xff0…

深度求索推出DeepSeek-V2:经济高效的多专家语言模型

AI苏妲己 深度求索发布了DeepSeek-V2混合专家&#xff08;MoE&#xff09;语言模型&#xff0c;每百万tokens&#xff0c;2元人民币价格&#xff0c;简直便宜到令人发指&#xff08;而且不是活动价格噢&#xff09;&#xff0c;可以说是继Groq以后&#xff0c;AI领域最惊艳的新…