选择排序就这么简单

从上一篇已经讲解了冒泡排序了,本章主要讲解的是选择排序,希望大家看完能够理解并手写出选择排序的代码,然后就通过面试了!如果我写得有错误的地方也请大家在评论下指出。

选择排序介绍和稳定性说明

来源百度百科:

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始(末尾)位置,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。

上面提到了选择排序是不稳定的排序方法,那我们的冒泡排序是不是稳定的排序方法呢?稳定的意思指的是什么呢?

判断某排序算法是否稳定,我们可以简单理解成:排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同

如果相同,则是稳定的排序方法。

如果不相同,则是不稳定的排序方法

如果排序前的数组是[3,3,1],假定我们使用选择排序的话,那第一趟排序后结果就是[1,3,3]。这个数组有两个相同的值,它俩在array[0]和array[1],结果经过排序,array[0]的跑到了array[2]上了。

那么这就导致:2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序不相同,因此,我们就说它是不稳定的

再回到上面的问题,上一篇说讲的冒泡排序是稳定的,主要原因是:俩俩比较的时候,没有对相等的数据进行交换(因为没必要)。因此它不存在2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序不相同。

那么稳定排序的好处是什么?

参考知乎回答@独行侠的回答:

如果我们只对一串数字排序,那么稳定与否确实不重要,因为一串数字的属性是单一的,就是数字值的大小。但是排序的元素往往不只有一个属性,例如我们对一群人按年龄排序,但是人除了年龄属性还有身高体重属性,在年龄相同时如果不想破坏原先身高体重的次序,就必须用稳定排序算法.

很清晰的指出,只有当在“二次”排序时不想破坏原先次序,稳定性才有意义

参考资料:

一、第一趟排序

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

首先,我们创建数组,找到它最大的值(这就很简单了):

int[] arrays = {2, 3, 1, 4, 3, 5, 1, 6, 1, 2, 3, 7, 2, 3};

//假定max是最大的

int max = 0;

for (int i = 0; i < arrays.length; i++) {

if (arrays[i] > max) {

max = arrays[i];

}

}

随后这个最大的数和数组末尾的数进行交换:

//使用临时变量,让两个数互换

int temp;

temp = arrays[11];

arrays[11] = arrays[13];

arrays[13] = temp;

那么经过第一趟排序,我们的最大值已经到了数组的末尾了。

二、第二趟排序

再次从数组获取最大的数(除了已经排好的那个):

int max2 = 0;

for (int i = 0; i < (arrays.length - 1); i++) {

if (arrays[i] > max2) {

max2 = arrays[i];

}

}

System.out.println(max2);

再将获取到的最大值与数组倒数第二位交换:

temp = arrays[7];

arrays[7] = arrays[12];

arrays[12] = temp;

经过第二次排序,已经能够将数组最大两个数进行排序了

三、代码简化

从前两趟排序其实我们就可以摸出规律了:

一个数组是需要n-1趟排序的(因为直到剩下一个元素时,才不需要找最大值)

每交换1次,再次找最大值时就将范围缩小1

查询当前趟数最大值实际上不用知道最大值是多少(上面我查出最大值,还要我手动数它的角标),知道它的数组角标即可,交换也是根据角标来进行交换

第一趟:遍历数组14个数,获取最大值,将最大值放到数组的末尾[13] 第二趟:遍历数组13个数,获取最大值,将最大值放到数组倒数第二位[12]

....

数组有14个数,需要13趟排序。

//记录当前趟数的最大值的角标

int pos ;

//交换的变量

int temp;

//外层循环控制需要排序的趟数

for (int i = 0; i < arrays.length - 1; i++) {

//新的趟数、将角标重新赋值为0

pos = 0;

//内层循环控制遍历数组的个数并得到最大数的角标

for (int j = 0; j < arrays.length - i; j++) {

if (arrays[j] > arrays[pos]) {

pos = j;

}

}

//交换

temp = arrays[pos];

arrays[pos] = arrays[arrays.length - 1 - i];

arrays[arrays.length - 1 - i] = temp;

}

System.out.println("公众号Java3y" + arrays);

四、选择排序优化

博主暂未想到比较好的优化方法,如果看到这篇文章的同学知道有更好的优化方法或者代码能够写得更好的地方,欢迎在评论下留言哦!

查到的这篇选择排序优化方法,感觉就把选择排序变了个味,大家也可以去看看:

他是同时获取最大值和最小值,然后分别插入数组的首部和尾部(这跟选择排序的原理好像差了点,我也不知道算不算)

五、扩展阅读

C语言实现

int findMaxPos ( int arr[], int n)

{

int max = arr[0];

int pos = 0;

for (int i = 1; i < n; i++) {

if (arr[i] > max) {

max = arr[i];

pos = i;

}

}

return pos;

}

void selectionSort ( int arr[], int n)

{

while (n > 1)

{

int pos = findMaxPos(arr, n);

int temp = arr[pos];

arr[pos] = arr[n - 1];

arr[n - 1] = temp;

n--;//

}

}

int main ()

{

int arr[] = {5, 32, 7, 89, 2, 3, 4, 8, 9};

selectionSort(arr, 9);

for (int i = 0; i < 9; i++)

cout << arr[i] << endl;

}

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y

java选择排序不稳定_选择排序就这么简单 - Java3y的个人空间 - OSCHINA - 中文开源技术交流社区...相关推荐

  1. java顺序表冒泡排序_冒泡排序就这么简单 - Java3y的个人空间 - OSCHINA - 中文开源技术交流社区...

    冒泡排序就这么简单 在我大一的时候自学c语言和数据结构,我当时就接触到了冒泡排序(当时使用的是C语言编写的).现在大三了,想要在暑假找到一份实习的工作,又要回顾一下数据结构与算法的知识点了. 排序对我 ...

  2. java重载覆盖隐藏_重载,覆盖以及隐藏 - osc_4dki3x9l的个人空间 - OSCHINA - 中文开源技术交流社区...

    重载是指同名函数具有不同的参数表.在同一访问区域内声明的几个具有不同参数列表(参数的类型.个数.顺序不同)的同名函数,程序会根据不同的参数列来确定具体调用哪个函数.对于重载函数的调用,编译期间确定,是 ...

  3. java实现自举_实现语言的自举 - 沙枣的个人空间 - OSCHINA - 中文开源技术交流社区...

    几乎所有的语言项目,其核心都是用更底层的语言写的. 底层语言大部分是 C,C++,而扩展这门语言的核心,就要用另外一种语言 去写.这给语言设计者较大的挑战. 开发语言必须具备底层语言的编写能力,而为了 ...

  4. JAVA刷CSDN访问量_刷csdn访问量 - 鹏城二少的个人空间 - OSCHINA - 中文开源技术交流社区...

    通过HttpURLConnection访问.只需改一下博客地址就行了,然后后台通过Jsoup解析博客的博客地址,然后通过多线程刷博客访问量(线程数量可根据自己电脑配置进行适当的修改 1.ListLin ...

  5. java萍方字体_苹方字体合集 - osc_flhsyn6i的个人空间 - OSCHINA - 中文开源技术交流社区...

    CSS font-family 中的苹方字体 苹方提供了六个字重,font-family 定义如下: 苹方-简 常规体 font-family: PingFangSC-Regular, sans-se ...

  6. java实现gdal栅格矢量化_gdal栅格矢量化 - osc_lfs4vsih的个人空间 - OSCHINA - 中文开源技术交流社区...

    #include "gdal_alg.h" 栅格矢量化功能用于将栅格数据生成矢量数据,通常用于分类图像.GDAL库中使用函数GDALPolygonize()或者函数GDALFPol ...

  7. java把abcedf字符串进行排序_字符串合并处理 - 一贱书生的个人空间 - OSCHINA - 中文开源技术交流社区...

    题目描述 按照指定规则对输入的字符串进行处理. 详细描述: 将输入的两个字符串合并. 对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序.这里的下标意思是字符在字符串 ...

  8. java电子报刊网站_采集电子报纸 - 杨尚川的个人页面 - OSCHINA - 中文开源技术交流社区...

    1.接口 /** *报纸采集器 * @author 杨尚川 */ public interface PaperCollector { /** * 下载当日报纸,一个文件对应一个版面 * @return ...

  9. 舞蹈链java实现_舞蹈链(DLX) - osc_kpp7htz3的个人空间 - OSCHINA - 中文开源技术交流社区...

    #舞蹈链(DLX) Tags:搜索 ##作业部落 ##评论地址 ##一.概述 特别特别感谢这位童鞋His blog 舞蹈链是一种优美的搜索,就像下面这样跳舞- 舞蹈链用于解决精确覆盖或者重复覆盖的问题 ...

最新文章

  1. PHP--isset()和unset()函数的用法
  2. Oxford Nanopore碱基识别(basecalling)软件性能大比拼
  3. mysql char varchar text 对比
  4. 【深度学习】深入浅出transformer内部结构
  5. 【集合论】二元关系 ( 定义域 | 值域 | 域 | 逆运算 | 逆序合成运算 | 限制 | 像 | 单根 | 单值 | 合成运算的性质 )
  6. php一句话图片木马过滤_php一句话图片木马怎么解析
  7. eclipse安装lombok插件 ,但是:lombok注解不起作用(亲测有效!)
  8. 如何在服务器上运行python程序_在服务器上配置运行(每天一则段子python程序)...
  9. codeforces 842 D. Vitya and Strange Lesson(01字典树+思维+贪心)
  10. 跨浏览器测试工具推荐
  11. android 代码循环,Android – 每5秒循环一部分代码
  12. ACdream 1417 Numbers
  13. 零件缝隙平行线距离检测4
  14. c语言烟花代码,C语言烟花程序
  15. matlab申明数值型的符号常量,实验四 MATLAB符号运算
  16. Best定理和MatrixTree定理 学习笔记
  17. limbo模拟器运行linux,Limbowin10镜像下载|Limbo模拟器win10镜像 可上网版_最火软件站...
  18. 跨境必看:跨境支付问题以及热门跨境支付方式的优劣势分析!
  19. pd.read_csv处理含中文的文件
  20. 吕 思 伟 ---- 潘 爱 民 :: ATL 介 绍( 二 )

热门文章

  1. python日志模块 限制日志记录数_python日志记录-logging模块
  2. weka使用训练集分类测试集_Giao 13C NMR计算分类训练集提高结构归属的准确性和可靠性...
  3. linux dhcp客户端配置文件,各个版本DHCP配置文件的整理
  4. linux下找不到sqlite3头文件,关于CentOS 7下sqlite3找不到的问题解决
  5. linux mysql5.6.30 配置_Linux(Red Hat 6 32位) 下安装Mysql5.6.30
  6. 【技术思路】极客时间-左耳听风-程序员攻略开篇
  7. 类间关系有很多种 UML
  8. PYTHON设计模式学习(3):Singleton pattern
  9. jquery节点查询
  10. linux系统调用函数---12