选择排序及其不稳定性介绍
【问题描述】
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”在后的相对状态。而且在后续的排序交换过程中,两者的相对位置依旧没有被换回来,导致选择排序前后,相同元素的相对前后相对位置发生了交换。所以,选择排序是不稳定的排序算法。
选择排序及其不稳定性介绍相关推荐
- 理解选择排序的不稳定性
选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了.那么, ...
- 数据结构与算法之选择排序
数据结构与算法之选择排序 目录 基本介绍 选择排序思想 代码实现 1. 基本介绍 选择排序也属于内部排序法,是从排序的数据中,按指定的规则选出某一元素,再依次交换位置后达到排序的目的 2. 选择排序思 ...
- 【Java数据结构与算法】第七章 冒泡排序、选择排序、插入排序和希尔排序
第七章 冒泡排序.选择排序.插入排序和希尔排序 文章目录 第七章 冒泡排序.选择排序.插入排序和希尔排序 一.冒泡排序 1.基本介绍 2.代码实现 二.选择排序 1.基本介绍 2.代码实现 三.插入排 ...
- 选择排序 介绍与java实现
排序是程序编码避不开的一个话题. 一组无规则有序数据,排序的方式有很多中,其中最笨的方法就是穷举,也就是全排列排序.n个数字的有n!种不同的排列方法,如果50个无规则数据进行全排列进行排序,及时一台高 ...
- 树选择排序(Tree Selection Sorting)介绍
简介 或许你有一个疑问:为什么堆排序使用二叉树,但是叫堆排序,而不是树排序? 因为堆排序的前身正是叫做树选择排序(Tree Selection Sorting),使用树结构,但是要稍微简单一些. 高德 ...
- 数据结构与算法:选择排序
数据结构与算法:选择排序 雪柯 大工生物信息 提笔为写给奋进之人 已关注 8 人赞同了该文章 引用自算法图解,作者[美] Aditya Bhargava 译袁国忠 特别备注:本书非原创,但部分内容自己 ...
- 输入法按照选字频率排序的C语言程序算法,算法与数据结构之选择排序(C语言)...
#include #include void SelectSort(int *a,int n);//预声明要调用的函数 int main(void) { int k; int x[]={,,,,,,, ...
- 排序---初级排序算法(选择排序、插入排序和希尔排序)
写在前面的话: 一枚自学Java和算法的工科妹子. 算法学习书目:算法(第四版) Robert Sedgewick 算法视频教程:Coursera Algorithms Part1&2 本文 ...
- 《大话数据结构》第9章 排序 9.4 简单选择排序
9.4.1 简单选择排序算法 爱炒股票短线的人,总是喜欢不断的买进卖出,想通过价差来实现盈利.但通常这种频繁操作的人,即使失误不多,也会因为操作的手续费和印花税过高而获利很少.还有一种做股票的人,他们 ...
- 【数据结构-排序】3.图解选择排序两种实现(简单选择排序/堆排序)
简单选择排序(选择排序) 排序思想 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置 然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾. 以此类推,直到所有元素 ...
最新文章
- nacos使用_springcloud~nacos在使用中需要注意的问题
- 互联网金融投放获客优化的讨论(新用户引导流程)
- linux 内核 工作队列,Linux内核新旧工作队列机制的剖析和比较
- C语言刷抖音源码,iOS多种刷新样式、音乐播放器、仿抖音视频、旅游App等源码...
- 2017年闰秒linux_2017年Linux专业人员的4个热门技能
- 将 LDAP 目录用于 Samba 认证
- sql 实现决策树_SQL Server中的Microsoft决策树
- Javascript获取For循环所用时间
- Linux私房菜阅读笔记
- 【java学习之路】(数据结构篇)002.栈和队列
- Diamond书写FPGA代码
- java银行叫号课程设计_课程设计-银行排队叫号机设计.doc
- 阿里云申请域名及域名配置https
- 免费、可商用的素材网站
- 用html实现贪吃蛇游戏思路,贪吃蛇游戏
- HDU—校赛—1004
- 阿里巴巴内部Java成长笔记,首次曝光!
- 3D激光开源项目——BLAM安装使用过程的一些问题
- 项目干系人是什么?如何有效管理项目干系人?
- 原生 js 拦截所有ajax请求 可用于油猴子
热门文章
- 12.凤凰架构:构建可靠的大型分布式系统 --- 容器间网络
- 1.Kubernetes权威指南 --- Kubernetes入门
- 4.企业安全建设指南(金融行业安全架构与技术实践) --- 内控合规管理
- 3.算法通关面试 --- 哈希表和集合
- 3.excel 生成 sql
- 23. Linux 主机上的用户信息传递
- 59. 预定义超全局变量
- 5. JavaScript RegExp 类型
- 9. Browser 对象 - Location 对象
- 如何从QC中导出测试用例及其测试步骤