当前位置: 首页 > news >正文

【排序算法】选择排序

一、定义:

        选择排序(Selection sort)是一种简单直观的排序算法。第一次从待排序的数据(元素)中选出最小(或最大)的一个元素,存放在数组的起始位置,然后再从剩余的没有排序的元素中寻找到最小(大)元素,然后放到已排序的数组的末尾。以此类推,直到全部待排序的数据元素的个数为零。对于数据量大的排序就没啥用了,排的比较慢。

二、原理:

1、 对于待排序的数组,我们从首元素开始,将首元素的下标用min记住,认为目前是最小的元素的下标;

2、开始遍历min所指向的元素后面的元素与每个元素和下标min所指向的元素进行比好,当遇到某个元素比min下标所指向的元素时,min里记录其下标,直到遍历结束为止。

3、此时找到了最小元素,和首元素(开始位置的元素)进行交换

4、首元素排序好,认为第一个元素为排序好的元素,进入第二次遍历,从未排序的元素开始(即该数组的第二个元素)将其下标用min记住,重复2-3,直到整个数组排序完成。

 动图用不了,画了遍历第一次的情况:

 三、时间复杂度:

无论最好还是最坏的情况都是O(N^2)

因为就算你是有序的也要遍历一遍,确认是否是最小的元素

 相同的100万个随机数据排序,选择排序堆排希尔排序进行比较效率,看结果就知道 为啥说选择排序用到的不多了吧,而且其稳定性也差;

四、代码:

这个是比较简单且没坑的写法!接下来还有一个思路

//交换数据
void Swp(int* p1, int* p2)
{assert(p1 && p2);int tmp = *p2;*p2 = *p1;*p1 = tmp;
}
//选择排序:
void SelectSort(int* a, int n)
{for (int i = 0; i < n; i++){int min = i;for (int j = i; j < n; j++){if (a[j] < a[min]){min = j;}}Swp(&a[min], &a[i]);}}

双向法👉一次性排好2个,一个maxi,一个mini,初始状态时,maxi和mini一起出发✨

接下来就是和上面一样的思路,分别进行比较,找到各自对应的最大值最小值 

 最小的元素到了首位置(begin),最大的到了尾位置(end);然后对2者中间当成未进行排序的数据,再次重复进行上述操作;此时从未排序的数组 从 下标1(begin+1)开始到下标4(end--)的位置结束;依次类推;

注意喽!!!实现这个时会出现一些问题哦!!不是这个方法不行,是个人没有考虑到方方面面!就是这个方法需要注意的地方

 一般人写好一次排序的代码可能会是这样的写的,从end+1开始比较的,一看是和自己比较没有意义,当然如果没有就算了,建议先完善好第一趟,再去考虑整体代码,减低错误;ok 回归正轨;下面听我分析  go——>✨✨✨✨✨✨✨✨

写了一个例子(单趟啊),如果刚好出现这种情况时,是不是就和我想要的结果不一样了,交换以后又回到了交换前,此时不得发现我们得考虑maxi在头位置不变的情况那么是不是当 maxi==beginmin = end  时是不是就是双方互相交换

 本来么,一开始想到的是直接换2个元素,但是仔细一想,我是指向的下标,那我是不是给maxi的指向改下;互换一下就可以了!!👉👉👉👉这样写憋说 还真有好处👍👍👍👍👍👍

✨好了,竟然我们能考虑了相等,为啥不考虑mini不在end的情况呢??咦~~~对哦,mini不在end的位置是怎么交换的??假设哈  🧑‍🎓🧑‍🎓咋看??看下结果🫰 maxi指向的还是最大的

这个时候我们在将maxi指向的元素和end(最后的位置)进行交换 问题就这么解决了!!!!!!!!!!!!

不知道有人会不会想如果minibegin的位置(下标为0)呢???其实不用考虑了,因为我们考虑maxibegin 是因为我们先将mini指向的元素头位置交换导致maxi丢掉了正确的指向,而mini指向begin时,不就是自己和自己交换么,不会影响双方的指向,当然不要考虑;没必要么

✨👉代码实现:

//交换数据
void Swp(int* p1, int* p2)
{assert(p1 && p2);int tmp = *p2;*p2 = *p1;*p1 = tmp;
}void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int maxi = begin;int mini = begin;for (int i = begin + 1; i <= end; i++){if (a[maxi] < a[i]){maxi = i;}if (a[mini] > a[i]){mini = i;}}Swp(&a[mini], &a[begin]);if (maxi == begin){maxi = mini;}Swp(&a[maxi], &a[end]);begin++;end--;}
}

好了,就到这了,还是那句话,排序算法👉先写单趟,再写整体;先写内部再写外部;先修心再修身❤️🫰

感                      谢                 观                       看

相关文章:

  • 浅谈线性化
  • 如何修改开源项目中发现的bug?
  • 使用Spring Boot自定义注解 + AOP实现基于IP的接口限流和黑白名单
  • 【Django】开发个人博客系统【1】
  • 【LeetCode】38.外观数列
  • 第P9周:YOLOv5-Backbone模块实现
  • Leetcode刷题笔记7
  • Java集合【超详细】2 -- Map、可变参数、Collections类
  • 探索Web前端三大主流框架:Angular、React和Vue.js
  • 城市公共交通IC卡消费流程
  • Superset二次开发之更新 SECRET_KEY
  • springboot+vue 社区养老服务系统
  • MySQL中,不能在一个DML(数据操纵语言,如INSERT, UPDATE, DELETE)语句中直接引用目标表进行子查询
  • python 第一天
  • Java----Maven详解
  • [deviceone开发]-do_Webview的基本示例
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 345-反转字符串中的元音字母
  • MySQL几个简单SQL的优化
  • Puppeteer:浏览器控制器
  • Python学习之路13-记分
  • ReactNative开发常用的三方模块
  • Redis 中的布隆过滤器
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 构建工具 - 收藏集 - 掘金
  • 如何实现 font-size 的响应式
  • 数据结构java版之冒泡排序及优化
  • 小程序开发中的那些坑
  • 浅谈sql中的in与not in,exists与not exists的区别
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (26)4.7 字符函数和字符串函数
  • (C#)一个最简单的链表类
  • (笔记自用)LeetCode:快乐数
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • ***测试-HTTP方法
  • ... 是什么 ?... 有什么用处?
  • .net refrector
  • .NET WPF 抖动动画
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NET多线程执行函数
  • .NET运行机制
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • :=
  • @EnableWebMvc介绍和使用详细demo
  • @PreAuthorize注解
  • [ 隧道技术 ] cpolar 工具详解之将内网端口映射到公网
  • [000-01-008].第05节:OpenFeign特性-重试机制
  • [20161214]如何确定dbid.txt
  • [51单片机] 简单介绍 (一)
  • [Android Studio 权威教程]断点调试和高级调试
  • [Angular] 笔记 20:NgContent