【问题描述】

1.给定任意长度的乱序整型数组,使用选择排序算法将其按照从小到大的顺序进行排列即可。

2.在1的基础上优化选择排序算法,要求每次遍历同时确定最小元素和最大元素,达到减少遍历次数的目的。

3.分析选择排序的时间复杂度和空间复杂度。

4.解释说明选择排序的不稳定性。

【问题解决】

1.原始选择排序代码如下:

public class SelectionSortTest {public static void main(String[] args) {int[] arr= {5,3,6,8,1,7,9,9,4,2,1};printIntArray(selectionSort(arr));} static int[] selectionSort(int[] arr) {for (int i = 0; i < arr.length-1; i++) {//定义最小元素的索引int minIndex=i;//查找最小元素索引for (int j = i+1; j < arr.length; j++) {minIndex=arr[j]<arr[minIndex]?j:minIndex;} //交换两个位置上的元素swapIntArray(arr, i, minIndex);System.out.print("第"+(i+1)+"次循环:");printIntArray(arr);}return arr;}//打印整型数组public static void printIntArray(int[] arr){for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}System.out.println();}//交换整型数组指定位置的元素public static void swapIntArray(int[] arr,int i,int j) {int temp = arr[i];arr[i]=arr[j];arr[j]=temp;}}

执行结果:

第1次循环:1 3 6 8 5 7 9 9 4 2 1
第2次循环:1 1 6 8 5 7 9 9 4 2 3
第3次循环:1 1 2 8 5 7 9 9 4 6 3
第4次循环:1 1 2 3 5 7 9 9 4 6 8
第5次循环:1 1 2 3 4 7 9 9 5 6 8
第6次循环:1 1 2 3 4 5 9 9 7 6 8
第7次循环:1 1 2 3 4 5 6 9 7 9 8
第8次循环:1 1 2 3 4 5 6 7 9 9 8
第9次循环:1 1 2 3 4 5 6 7 8 9 9
第10次循环:1 1 2 3 4 5 6 7 8 9 9
1 1 2 3 4 5 6 7 8 9 9 

2.优化后的代码:

public class SelectionSortTest {public static void main(String[] args) {int[] arr= {5,3,6,8,1,7,9,9,4,2,1};printIntArray(selectionSort(arr));}static int[] selectionSort(int[] arr) {for (int i = 0; i <= arr.length-(1+i); i++) {int maxlength = arr.length-(1+i);//定义最小元素的索引int minIndex=i;//定义最大元素索引int maxIndex=i;//定位到最小值索引和最大值索引for (int j = i+1; j <= maxlength; j++) {minIndex=arr[j]<arr[minIndex]?j:minIndex;maxIndex=arr[j]>arr[maxIndex]?j:maxIndex;}//交换指定位置上的元素SelectionSortTest.swapIntArray(arr, i, minIndex);SelectionSortTest.swapIntArray(arr, maxlength, maxIndex);if(arr[maxlength-1]>arr[maxlength]){SelectionSortTest.swapIntArray(arr, maxlength-1, maxlength);}System.out.print("第"+(i+1)+"次循环:");SelectionSortTest.printIntArray(arr);}return arr;}//打印整型数组public static void printIntArray(int[] arr){for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}System.out.println();}//交换整型数组指定位置的元素public static void swapIntArray(int[] arr,int i,int j) {int temp = arr[i];arr[i]=arr[j];arr[j]=temp;}
}

执行结果:

第1次循环:1 3 6 8 5 7 1 9 4 2 9
第2次循环:1 1 6 8 5 7 3 2 4 9 9
第3次循环:1 1 2 4 5 7 3 6 8 9 9
第4次循环:1 1 2 3 5 6 4 7 8 9 9
第5次循环:1 1 2 3 4 5 6 7 8 9 9
第6次循环:1 1 2 3 4 5 6 7 8 9 9
1 1 2 3 4 5 6 7 8 9 9 

3.选择排序使用双层循环,最消耗时间的代码是内层循环里定位目标元素索引的代码,即:

//定位到最小值索引
for (int j = i+1; j <= arr.length-(1+i); j++) {minIndex=arr[j]<arr[minIndex]?j:minIndex;//此行代码是最消耗时间的
}

若数组长度为n,则该行代码执行次数是:(n-1)+(n-2)+......2+1,所以时间复杂度为:,由于选择排序本身的特性(遍历元素并在内层循环确定指定元素的索引然后进行元素交换,必然会使用(n*n)数量级的时间),不管在最好还是最坏的情况下,时间复杂度都是

空间上除了目标数组本身以外没有使用额外的数据结构,因此空间复杂度为

4.只要能够证明经过选择排序后,大小相同的两个元素,相对前后位置对换了,就可以说明选择排序算法是不稳定的。我们可以在上列的代码中加入相应的打印语句,查看选择排序的整个过程:

public class SelectionSortTest {public static void main(String[] args) {int[] arr= {5,3,3,8,1,6,7,9,4,2};printIntArray(selectionSort(arr));} static int[] selectionSort(int[] arr) {for (int i = 0; i < arr.length-1; i++) {//定义最小元素的索引int minIndex=i;//查找最小元素索引for (int j = i+1; j < arr.length; j++) {minIndex=arr[j]<arr[minIndex]?j:minIndex;} System.out.print("第"+(i+1)+"次循环:");printIntArray(arr);//交换两个位置上的元素swapIntArray(arr, i, minIndex);System.out.print("索引["+i+"]与["+minIndex+"]即元素‘"+arr[minIndex]+"’与‘"+arr[i]+"’交换:");printIntArray(arr);}return arr;}//打印整型数组public static void printIntArray(int[] arr){for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}System.out.println();}//交换整型数组指定位置的元素public static void swapIntArray(int[] arr,int i,int j) {int temp = arr[i];arr[i]=arr[j];arr[j]=temp;}}

执行结果:

第1次循环:5 3 3 8 1 6 7 9 4 2
索引[0]与[4]即元素‘5’与‘1’交换:1 3 3 8 5 6 7 9 4 2
第2次循环:1 3 3 8 5 6 7 9 4 2
索引[1]与[9]即元素‘3’与‘2’交换:1 2 3 8 5 6 7 9 4 3
第3次循环:1 2 3 8 5 6 7 9 4 3
索引[2]与[2]即元素‘3’与‘3’交换:1 2 3 8 5 6 7 9 4 3
第4次循环:1 2 3 8 5 6 7 9 4 3
索引[3]与[9]即元素‘8’与‘3’交换:1 2 3 3 5 6 7 9 4 8
第5次循环:1 2 3 3 5 6 7 9 4 8
索引[4]与[8]即元素‘5’与‘4’交换:1 2 3 3 4 6 7 9 5 8
第6次循环:1 2 3 3 4 6 7 9 5 8
索引[5]与[8]即元素‘6’与‘5’交换:1 2 3 3 4 5 7 9 6 8
第7次循环:1 2 3 3 4 5 7 9 6 8
索引[6]与[8]即元素‘7’与‘6’交换:1 2 3 3 4 5 6 9 7 8
第8次循环:1 2 3 3 4 5 6 9 7 8
索引[7]与[8]即元素‘9’与‘7’交换:1 2 3 3 4 5 6 7 9 8
第9次循环:1 2 3 3 4 5 6 7 9 8
索引[8]与[9]即元素‘9’与‘8’交换:1 2 3 3 4 5 6 7 8 9
1 2 3 3 4 5 6 7 8 9

我们可以观察到,对于初始数组int[] arr= {5,3,3,8,1,6,7,9,4,2};进行选择排序过程中,原本位于索引[1]上的元素“3”在第二次循环里和索引[9]上的元素“2”交换位置,使得原本索引[1]位置上的元素“3”在前,索引[2]位置上的元素“3”在后的相对状态,变成了索引[2]位置上的元素“3”在前,索引[1]位置上的元素“3”在后的相对状态。而且在后续的排序交换过程中,两者的相对位置依旧没有被换回来,导致选择排序前后,相同元素的相对前后相对位置发生了交换。所以,选择排序是不稳定的排序算法。

选择排序及其不稳定性介绍相关推荐

  1. 理解选择排序的不稳定性

    选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了.那么, ...

  2. 数据结构与算法之选择排序

    数据结构与算法之选择排序 目录 基本介绍 选择排序思想 代码实现 1. 基本介绍 选择排序也属于内部排序法,是从排序的数据中,按指定的规则选出某一元素,再依次交换位置后达到排序的目的 2. 选择排序思 ...

  3. 【Java数据结构与算法】第七章 冒泡排序、选择排序、插入排序和希尔排序

    第七章 冒泡排序.选择排序.插入排序和希尔排序 文章目录 第七章 冒泡排序.选择排序.插入排序和希尔排序 一.冒泡排序 1.基本介绍 2.代码实现 二.选择排序 1.基本介绍 2.代码实现 三.插入排 ...

  4. 选择排序 介绍与java实现

    排序是程序编码避不开的一个话题. 一组无规则有序数据,排序的方式有很多中,其中最笨的方法就是穷举,也就是全排列排序.n个数字的有n!种不同的排列方法,如果50个无规则数据进行全排列进行排序,及时一台高 ...

  5. 树选择排序(Tree Selection Sorting)介绍

    简介 或许你有一个疑问:为什么堆排序使用二叉树,但是叫堆排序,而不是树排序? 因为堆排序的前身正是叫做树选择排序(Tree Selection Sorting),使用树结构,但是要稍微简单一些. 高德 ...

  6. 数据结构与算法:选择排序

    数据结构与算法:选择排序 雪柯 大工生物信息 提笔为写给奋进之人 已关注 8 人赞同了该文章 引用自算法图解,作者[美] Aditya Bhargava 译袁国忠 特别备注:本书非原创,但部分内容自己 ...

  7. 输入法按照选字频率排序的C语言程序算法,算法与数据结构之选择排序(C语言)...

    #include #include void SelectSort(int *a,int n);//预声明要调用的函数 int main(void) { int k; int x[]={,,,,,,, ...

  8. 排序---初级排序算法(选择排序、插入排序和希尔排序)

    写在前面的话: 一枚自学Java和算法的工科妹子. 算法学习书目:算法(第四版) Robert Sedgewick 算法视频教程:Coursera  Algorithms Part1&2 本文 ...

  9. 《大话数据结构》第9章 排序 9.4 简单选择排序

    9.4.1 简单选择排序算法 爱炒股票短线的人,总是喜欢不断的买进卖出,想通过价差来实现盈利.但通常这种频繁操作的人,即使失误不多,也会因为操作的手续费和印花税过高而获利很少.还有一种做股票的人,他们 ...

  10. 【数据结构-排序】3.图解选择排序两种实现(简单选择排序/堆排序)

    简单选择排序(选择排序) 排序思想 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置 然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾. 以此类推,直到所有元素 ...

最新文章

  1. nacos使用_springcloud~nacos在使用中需要注意的问题
  2. 互联网金融投放获客优化的讨论(新用户引导流程)
  3. linux 内核 工作队列,Linux内核新旧工作队列机制的剖析和比较
  4. C语言刷抖音源码,iOS多种刷新样式、音乐播放器、仿抖音视频、旅游App等源码...
  5. 2017年闰秒linux_2017年Linux专业人员的4个热门技能
  6. 将 LDAP 目录用于 Samba 认证
  7. sql 实现决策树_SQL Server中的Microsoft决策树
  8. Javascript获取For循环所用时间
  9. Linux私房菜阅读笔记
  10. 【java学习之路】(数据结构篇)002.栈和队列
  11. Diamond书写FPGA代码
  12. java银行叫号课程设计_课程设计-银行排队叫号机设计.doc
  13. 阿里云申请域名及域名配置https
  14. 免费、可商用的素材网站
  15. 用html实现贪吃蛇游戏思路,贪吃蛇游戏
  16. HDU—校赛—1004
  17. 阿里巴巴内部Java成长笔记,首次曝光!
  18. 3D激光开源项目——BLAM安装使用过程的一些问题
  19. 项目干系人是什么?如何有效管理项目干系人?
  20. 原生 js 拦截所有ajax请求 可用于油猴子

热门文章

  1. 12.凤凰架构:构建可靠的大型分布式系统 --- 容器间网络
  2. 1.Kubernetes权威指南 --- Kubernetes入门
  3. 4.企业安全建设指南(金融行业安全架构与技术实践) --- 内控合规管理
  4. 3.算法通关面试 --- 哈希表和集合
  5. 3.excel 生成 sql
  6. 23. Linux 主机上的用户信息传递
  7. 59. 预定义超全局变量
  8. 5. JavaScript RegExp 类型
  9. 9. Browser 对象 - Location 对象
  10. 如何从QC中导出测试用例及其测试步骤