By Mejias
选择排序算法
选择排序是所有的数和顺序下来的某一个元素对比,冒泡排序则是传递性的两两对比
第一种写法:从左到右缩小范围依次选出最小值
/**
选择排序算法
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,
顺序放在已排好序的子序列的最后,直到全部待排序的数据元素排完。
选择排序是不稳定的排序算法
*/
/*
34 4 56 17 90 65
4 34 56 17 90 65 第一轮 对比5次交换一次
17 56 34 90 65 第二轮 对比4次交换一次
34 56 90 65 第三轮 对比3次交换一次
56 90 65 第四轮 对比2次交换一次
65 90 第五轮 对比1次交换一次
*/
public class Test3{
public static void main(String[] args){
int[] nums = {34,4,56,17,90,65};//待排序的数列
int minIndex = 0;//用于记录每次比较的最小值下标
for (int i=0;i<nums.length-1;i++){//外循环用于控制轮数
minIndex = i;//每轮假设一个最小值下标
for(int j=i+1;j<nums.length;j++){//内循环获得最小数的下标
if(nums[minIndex]>nums[j]){
minIndex = j;
}
}
//判断需要交换的数下标是否为自己
if(minIndex!=i){//外循环内的判断使得只交换一次,交换是排序的基础
nums[i] = nums[i]+nums[minIndex];
nums[minIndex] = nums[i] - nums[minIndex];
nums[i] = nums[i] - nums[minIndex];
}
}
//输出结果
for(int n: nums){
System.out.print(n+ ",");
}
}
}
第二种写法:从右到左缩小范围依次选出最大值(从后往前)
/**
选择排序算法
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最前,直到全部待排序的数据元素排完。
选择排序是不稳定的排序算法
*/
/*
34 4 56 17 90 65
34 4 56 17 65 90 第一轮 对比5次交换一次
34 4 56 17 65 第二轮 对比4次交换一次
34 4 17 56 第三轮 对比3次交换一次
17 4 34 第四轮 对比2次交换一次 //选择排序和冒泡排序的交换位置不同的是,选择排序不是临近交换
4 17 第五轮 对比1次交换一次
*/
public class Test4{
public static void main(String[] args){
int[] nums = {34,4,56,17,90,65};//待排序的数列
int maxIndex = nums.length-1;//用于记录每次比较的最大值下标
for (int i=nums.length-1;i>0;i--){//外循环用于控制轮数
maxIndex = i;//每轮假设一个最大值下标
for(int j=i-1;j>=0;j--){//内循环获得最大数的下标
if(nums[maxIndex]<nums[j]){
maxIndex = j;
}
}
//判断需要交换的数下标是否为自己
if(maxIndex!=i){//外循环内的判断使得只交换一次,交换是排序的基础
nums[i] = nums[i]+nums[maxIndex];
nums[maxIndex] = nums[i] - nums[maxIndex];
nums[i] = nums[i] - nums[maxIndex];
}
}
//输出结果
for(int n: nums){
System.out.print(n+ ",");
}
}
}
插入排序算法
第一种写法:从后往前插入
/**
直接插入排序算法
(从后往前找到合适的位置后插入)
基本思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的子序列的合适位置(从后向前找到合适位置后),直到全部插入排序完成为止。
*/
public class Test1{
public static void main (String[] args){
int[] nums = {34,4,56,17,90,65};//待排序的数列
//外循环控制比较的轮数;
for(int i=1;i<nums.length;i++){
int temp=nums[i];//记录操作数
int j=0;
for(j=i-1;j>=0;j--){
if(nums[j]>temp){
nums[j+1]=nums[j];//从数组移出操作数,将待插入位置后的数向后移一个index
}else{
break;
}
}
if(nums[j+1]!=temp){
nums[j+1] = temp;//在待插入位置的值替换为操作数
}
}
//输出结果:
for(int n:nums){
System.out.print(n+",");
}
}
}
/*
34 4 56 17 90 65
*/
第二种写法:从前往后插入
/**
直接插入排序算法
(从前往后找到合适位置后插入)
基本思想:每步将一个待排序的记录,按其顺序码大小插入到后面已经排序的子序列的合适位置(从后向前找到合适位置后)。
直到全部插入排序为止
*/
public class Test2{
public static void main (String[] args){
int[] nums = {34,4,56,17,90,65};//待排序的数列
//外循环控制比较的轮数;
for(int i=nums.length-2;i>=0;i--){
int temp=nums[i];//记录操作数
int j=0;
for(j=i+1;j<=nums.length-1;j++){
if(nums[j]<temp){
nums[j-1]=nums[j];//从数组移出操作数,将待插入位置后的数向前移一个index
}else{
break;
}
}
if(nums[j-1]!=temp){
nums[j-1] = temp;//在待插入位置的值替换为操作数
}
}
//输出结果:
for(int n:nums){
System.out.print(n+",");
}
}
}
/*
34 4 56 17 90 65
65 90 //第一轮,比较1次
17 65 90 //第二轮,比较2次
17 56 65 90 //第三轮,比较3次
4 17 56 65 90 //第四轮,比较4次
4 17 34 56 65 90 //第五轮,比较5次
*/
插入排序与选择排序的对比
1.插入排序是对已排序的子序列操作,选择排序完全是对待排序数列操作
从内循环的条件可以看出,插入排序是往操作数之前的方向走,选择排序是往操作数时候的方向走
插入排序
选择排序
2.插入排序是在排序好的子序列插入待排序数列的首个元素,选择排序是选出待排序数列最小元素和待排序数列首个元素替换位置
插入排序
选择排序
3.插入排序和选择排序对比次数不同,替换次数也不同
插入排序在第N轮比较N次,而选择排序在第N轮比较length-N次
插入排序
选择排序
4.选择排序类似最大最小值算法(在待排序数列中),只是增加了替换环节,而插入排序也运用了最大最小值算法(在已排序子数列中),即将待插入数作为分割,在已排好序的子数列前后分别是最大数和最小数
插入排序
选择排序