八大算法排序@选择排序(C语言版本)

news2024/11/15 18:26:48

目录

  • 选择排序
    • 概念
    • 算法思想
      • 示例
      • 步骤1
      • 步骤2
      • 步骤...n
      • 最后一步
    • 代码实现
    • 时间复杂度
    • 空间复杂度
    • 特性总结

选择排序

概念

  选择排序(Selection Sort)是一种简单直观的排序算法。基本思想是在未排序的序列中找到最小(或最大)元素,然后将其放到序列的起始位置,再从剩余未排序的序列中找到最小(或最大)元素,放到已排序序列的末尾。以此类推,直到整个序列排序完成。



算法思想

主要思路就是找出未排序的序列中的最小/最大的元素,置换到有序序列的尾巴上,实现有序序列的升序/降序效果。当有序序列的长度等于数组长度时,数组排序完成。我们拿实现升序的选择排序来进行模拟演变。

示例

如下是数组arr1 = { 6 , 4 , 3 , 9 , 2 , 1 , 5 , 7 , 8 }初始状态下的图文演示:
初始

其中,变量begin、end是数组的第一个和最后一个元素的下标,变量mini用来存储未排序数组的最小元素的下标。



步骤1

第一次,在为排序的数组序列中,找到序列中最小的元素的下标:
第一步

如图,找到最小的元素1,将元素1的下标5存到mini变量中,然后将arr1[begin] 和 arr1[mini] 两个元素位置互换,begin再加1,因为begin是未排序的序列的第一个元素的下标值。



步骤2

第二次,继续在为排序的数组序列中,找到序列中最小的元素的下标:

第二步

在未排序的数组中最小的元素2的下标为4,存到mini变量中,然后将arr1[begin] 和 arr1[mini] 两个元素位置互换,begin再加1。



步骤…n

重复以上的步骤,具体的我就不多加演示,下面是最后一次的排序演示图:



最后一步

最终
当begin和end 相等时,此时整个数组已经有序,已经排序成升序的效果。

以上便是关于选择排序的相关图形流程,下面结合图形流程,编写代码。





代码实现

选择排序的步骤如下:
初始化: 将序列分为两部分,一部分为已排序的部分,一部分为未排序的部分。初始时,已排序部分为空。
步骤2:在未排序部分中找到最小元素: 遍历未排序部分,找到最小的元素。
步骤3:交换: 将找到的最小元素与未排序部分的第一个元素交换位置,将其加入到已排序部分。
重复: 重复步骤2和步骤3,直到未排序部分为空。



代码实现:

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


//选择排序
void SelectSort(int* a, int n)
{
	assert(a);

	int begin = 0;		// 有序数组的最后一个元素的下标
	int end = n - 1;	// 数组最后一个元素的下标

	int mini = begin;
	// 当begin==end时,整个数组已经排序完,退出循环。否则一直循环进行排序
	while (begin < end)
	{
		// 在未排序的序列里找出最小的元素的下标,存到变量mini中
		for (int i = begin + 1; i <= end; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;
			}
		}
		// 将序列中最小的数组置换到前面,实现升序的排序效果
		Swap(&a[begin], &a[mini]);		//小的放在最前面
		begin++;  // 有序的数组加1,最后一个元素的下标随之加1
	}
	// 实现数组的升序排序。
}

以上,便是选择排序的实现代码,在此基础上,我们还可以进一步的改进。原先是在未排序的序列中找出最小/最大的元素,置换到排好序的序列的末尾中,一次只能排一个数
现在改进点:每次排两个数,即在未排序的序列中,找出最大和最小的元素下标,分别存到变量中。然后将最大的排到最后面,最小的排到最前面(升序)。然后begin加1,end减1,接着做重复的动作,每次排好两个数。如下图:

在这里插入图片描述



代码实现如下:

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


//选择排序
void SelectSort(int* a, int n)
{
	assert(a);

	int begin = 0;
	int end = n - 1;
	int maxi = begin;
	int mini = begin;

	while (begin < end)
	{
		for (int i = begin + 1; i <= end; i++)
		{
			if (a[i] > a[maxi])
			{
				maxi = i;
			}

			if (a[i] < a[mini])
			{
				mini = i;
			}
		}


		Swap(&a[end], &a[maxi]);		//大的放在最后面
		if (mini == end)
		{
			mini = maxi;
		}
		Swap(&a[begin], &a[mini]);		//小的放在最前面
		begin++;
		end--;
		maxi = mini = begin;
	}

}

需要注意:边界的问题。



时间复杂度

O(N^2)。
不管是一次只排一个数的选择排序,还是一次排两个数的选择排序,时间复杂度都是O(N^2),当然后者肯定比前者效率更高一点,为 O(N^2 / 2),但是时间复杂度的计算是不计入系数的。所以两者的时间复杂度都是O(N^2)。



空间复杂度

O(1)。
在原数组上改动,没有用到多余的空间,所以空间复杂度为O(1)。



特性总结

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

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

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

相关文章

[论文阅读] Revisiting Feature Propagation and Aggregation in Polyp Segmentation

[论文地址] [代码] [MICCAI 23] Abstract 息肉的准确分割是筛查过程中有效诊断结直肠癌的关键步骤。 由于能够有效捕获多尺度上下文信息&#xff0c;普遍采用类似UNet 的编码器-解码器框架。 然而&#xff0c;两个主要限制阻碍了网络实现有效的特征传播和聚合。 首先&#xff…

Eslint+Prettier

1.Eslint js验证的规则标准,Vue也有自己的独特的验证规则,vue-eslint-plugin属于vue自己的验证规则。 如果不想报错,可以在package.json/rules里面进行关闭,默认是开启的,默认缩进是两个空格。 2.Prettier - Code formatter 使写代码更加的美观 可选的配置项: 例如: module…

C语言编译器(C语言编程软件)完全攻略(第二十九部分:Linux GCC简明教程(使用GCC编写C语言程序))

介绍常用C语言编译器的安装、配置和使用。 二十九、Linux GCC简明教程&#xff08;使用GCC编写C语言程序&#xff09; 市面上常见的 Linux 都是发行版本&#xff0c;典型的 Linux 发行版包含了 Linux 内核、桌面环境&#xff08;例如 GNOME、KDE、Unity 等&#xff09;和各种…

光速爱购--靠谱的SpringBoot项目

简介 这是一个靠谱的SpringBoot项目实战&#xff0c;名字叫光速爱购。从零开发项目&#xff0c;视频加文档&#xff0c;十天就能学会开发JavaWeb项目。 教程路线是&#xff1a;搭建环境> 安装软件> 创建项目> 添加依赖和配置> 通过表生成代码> 编写Java代码&g…

1018:奇数偶数和1028:I love 闰年!和1029:三角形判定

1018&#xff1a;奇数偶数 要求&#xff1a;输入一个整数&#xff0c;判断该数是奇数还是偶数。如果该数是奇数就输出“odd”&#xff0c;偶数就输出“even”&#xff08;输出不含双引号&#xff09;。 输入样例&#xff1a;8 输出样例&#xff1a;even 程序流程图&#xff1a…

Dockerfile的EXPOSE

文章目录 环境总结测试使用EXPOSE测试1&#xff1a;不做端口映射测试2&#xff1a;-p 8080:80测试3&#xff1a;-P测试4&#xff1a;--networkhost 不使用EXPOSE 参考 环境 RHEL 9.3Docker Community 24.0.7 总结 如果懒得看测试的详细信息&#xff0c;可以直接看结果&#…

算法通关村番外篇-优先队列

大家好我是苏麟 , 今天聊聊优先队列 . 优先队列 我们了解优先队列之前先说说队列 . 队列的特点是什么&#xff1f; 队列的特点是先进先出&#xff08;FIFO&#xff09;。 入队列&#xff0c;将新元素置于队尾&#xff1a; 出队列&#xff0c;队头元素最先被移出&#xff1a…

每周一算法:倍增法查找位置

倍增法 倍增法&#xff08;Binary Lifting&#xff09;&#xff0c;顾名思义&#xff0c;就是利用“以翻倍的速度增长”的思想来解决问题的一类算法&#xff0c;它能够使线性的处理转化为对数级的处理&#xff0c;大大地优化时间复杂度。这个方法在很多算法中均有应用&#xf…

密码学中的Hash函数

目录 一. 介绍 二. hash函数的五个基本性质 &#xff08;&#xff11;&#xff09;压缩性 &#xff08;&#xff12;&#xff09;正向计算简单性 &#xff08;&#xff13;&#xff09;逆向计算困难性 &#xff08;&#xff14;&#xff09;弱无碰撞性 &#xff08;&…

ARMv8-AArch64 的异常处理模型详解之异常等级、执行状态以及安全状态

ARMv8-AArch64 的异常处理模型详解 一&#xff0c;特权和异常等级1.1 异常等级 Exception levels 二&#xff0c;特权的类型2.1 内存特权2.2 访问寄存器的特权 三&#xff0c;执行状态和安全状态3.1 执行状态 Execution states3.2 执行状态切换 3.3 安全状态 Security states3.…

知识图谱之汽车实战案例综述与前瞻分析

知识图谱的前置介绍 什么是知识图谱 知识图谱本质(Knowledge Graph&#xff09;上是一种叫做语义网络(semantic network &#xff09; 的知识库&#xff0c;即具有有向图结构的一个知识库&#xff1b;图的结点代表实体&#xff08;entity&#xff09;或者概念&#xff08;con…

【Python学习】Python学习6-循环语句

目录 【Python学习】【Python学习】Python学习6-循环语句 前言for循环for循环示例通过序列索引迭代循环使用 else 语句 while循环while循环示例continue和 break无限循环循环使用 else 语句简单语句组 嵌套循环Python for 循环嵌套语法&#xff1a;Python while 循环嵌套语法&…

基于springboot的sql防注入过滤器

目录 何为SQL注入基于springboot的sql防注入过滤器 回到顶部 何为SQL注入 SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现…

Java-IO流-15

文件操作 文件创建 package com.edu.file;import org.junit.jupiter.api.Test;import java.io.File; import java.io.IOException;public class Demo01 {public static void main(String[] args) {}Test//方式1public void create01(){String filePath "D:\\new1.txt&q…

Postman实现压力测试

从事软件开发对于压力测试并不陌生,常见的一些压测软件有Apache JMeter LoadRunner Gatling Tsung 等,这些都是一些比较专业的测试软件,对于我的工作来说一般情况下用不到这么专业的测试,有时候需要对一些接口进行压力测试又不想再安装新软件,那么可以使用Postman来实现对…

C语言基础知识(6):UDP网络编程

UDP 是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在 UDP 的情况下&#xff0c;虽然可以确保发送消息的大小&#xff0c;却不能保证消息一定会到达。因此&#xff0c;应用有时会根据自己的需要进行重发处理。 1.UDP协议的主要特点&#xff1a; &#xf…

一文带你弄懂 V8 数组的快速 / 字典模式

V8 是如何处理数组的&#xff1f; 问题 先抛出一个问题&#xff0c;下面两端代码哪个的效率更高&#xff1f; const arr []; for(let i 0; i < 10000000; i) {arr[i] 1; }const arr []; arr[10000000 - 1] 1; for(let i 0; i < 10000000; i) {arr[i] 1; }答案是…

PHP代码审计之实战审代码篇2

4. 仔细观察如下代码&#xff0c;思考代码有什么缺陷&#xff0c;可能由此引发什么样的问题&#xff1f; <?php require_once("/home/rconfig/classes/usersession.class.php"); require_once("/home/rconfig/classes/ADLog.class.php"); require_onc…

springboot+redisTemplate多库操作

单库操作 我做了依赖管理&#xff0c;所以就不写版本号了添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>配置文件 spring:redis:database: 2…

钡铼技术BL110智能网关功能介绍 | PLC程序的上传和下载

在工业自动化系统中&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;是一种常见的控制设备。通常情况下&#xff0c;PLC被用于监控、控制和调节生产过程中的各种设备和机器。而PLC一旦出现故障&#xff0c;就会影响到下控设备的工作状态&#xff0c;进而影响整个工厂的…