/**
* 思想:
* 拿到固定位置的数,依此和后面的数进行比较,找到应该在的位置,则交换位置
* 实现方式:
* 从小到大排序,则从头找最小的,最小的放在最前面,比较一轮交换一次
* <p>
* 区别于冒泡排序:
* 冒泡是相邻的两两比较,满足则交换(1V1)
* 选择是固定位置和其余位置比较,满足则交换(1V5)
*/
public class TestSelectSort {
public static void main(String[] args) {
int[] array = {9, 5, 3, 7, 1};
// selectSort1(array);
// System.out.println();
/* selectSort2(array);*/
selectSort3(array);
}
//打印数组
public static void printArray(int[] array) {
for (int i : array) {
System.out.print(i + "\t");
}
System.out.println();
}
/**
* 思路1:固定的位置和其后每一个比较,满足条件则交换位置,此时是两两交换
* @param a
*/
public static void selectSort1(int[] a) {
//第一轮,确定最小的数,放在第一位 0--1 2 3 4
if (a[0] > a[1]) {
int temp = a[0];
a[0] = a[1];
a[1] = temp;
}
if (a[0] > a[2]) {
int temp = a[0];
a[0] = a[2];
a[2] = temp;
}
if (a[0] > a[3]) {
int temp = a[0];
a[0] = a[3];
a[3] = temp;
}
if (a[0] > a[4]) {
int temp = a[0];
a[0] = a[4];
a[4] = temp;
}
printArray(a);
//第二轮,确定第二小的数,放在第二位 1--2 3 4
if (a[1] > a[2]) {
int temp = a[1];
a[1] = a[2];
a[2] = temp;
}
if (a[1] > a[3]) {
int temp = a[1];
a[1] = a[3];
a[3] = temp;
}
if (a[1] > a[4]) {
int temp = a[1];
a[1] = a[4];
a[4] = temp;
}
printArray(a);
//第三轮:找到第三小的数,放在第三位 2--3 4
if (a[2] > a[3]) {
int temp = a[2];
a[2] = a[3];
a[3] = temp;
}
if (a[2] > a[4]) {
int temp = a[2];
a[2] = a[4];
a[4] = temp;
}
printArray(a);
//第四轮,找到第四小的数,放在第四位 3--4
if (a[3] > a[4]) {
int temp = a[3];
a[3] = a[4];
a[4] = temp;
}
printArray(a);
}
/***
* 在最基本的思路上进行代码优化
* @param a
*/
public static void selectSort2(int[] a) {
//第一轮 0--1 2 3 4
for (int i = 1; i <=4; i++) {
if (a[0] > a[i]) {
int temp = a[0];
a[0] = a[i];
a[i] = temp;
}
}
//规律 1 0 i
printArray(a);
//第二轮 1--2 3 4
for (int i = 2; i <=4; i++) {
if (a[1] > a[i]) {
int temp = a[1];
a[1] = a[i];
a[i] = temp;
}
}
//规律 2 1 i
printArray(a);
//第三轮 2--3 4
for (int i = 3; i <=4; i++) {
if (a[2] > a[i]) {
int temp = a[2];
a[2] = a[i];
a[i] = temp;
}
}
//规律 3 2 i
printArray(a);
//第四轮 3--4
for (int i = 4; i <=4; i++) {
if (a[3] > a[i]) {
int temp = a[2];
a[2] = a[i];
a[i] = temp;
}
}
//规律 4 3 i
printArray(a);
}
/**
* 在selectSort2的基础上进行优化整合
* @param a
*/
public static void selectSort3(int[] a){
/*
1.先浓缩,保证结果正确
*/
// for (int j = 1; j <=4; j++) {//四轮
// for (int i = 1; i <=4 ; i++) {//比较
// if(a[i-1]>a[i]){
// int temp =a[i-1];
// a[i-1] = a[i];
// a[i] = temp;
// }
// }
// }
// printArray(a);
/*
2.把4替换为数组长度,以便适应不同的数组
*/
// for (int j = 1; j <=a.length-1; j++) {//四轮
// for (int i = 1; i <=a.length-1 ; i++) {//比较
// if(a[i-1]>a[i]){
// int temp =a[i-1];
// a[i-1] = a[i];
// a[i] = temp;
// }
// }
// }
// printArray(a);
/**
* 把j i 替换为下标0开始,
* 缩减范围
* j=0 j<a.length-1 轮次j和下标联系
* i=j+1 i<=a.length-1 比较次数i和轮次j联系
* i-1 = j 交换变换,i-1=j
* i<a.length 等同于i<=a.length-1
*/
// for (int j = 0; j <a.length-1; j++) {//四轮
// for (int i = j+1; i <a.length ; i++) {//比较
// if(a[j]>a[i]){
// int temp =a[j];
// a[j] = a[i];
// a[i] = temp;
// }
// }
// }
// printArray(a);
/**
* 以上方式和冒泡没有明显区别,都是比较一次交换一次
* 思路2:
* 以固定位置的数作为最小值,依此和后面的数进行比较,记录最小值下标,一轮结束,交换位置
*/
// for (int j = 0; j <a.length-1; j++) {//四轮
// int minIndex = j;
// for (int i = j+1; i <a.length ; i++) {//比较
// if(a[minIndex]>a[i]){
// minIndex = i;
// }
// }
// //固定位置为j,minIndex为最小值的下标位置,那么最终是j和minIndex两个位置元素
// int temp = a[minIndex];
// a[minIndex] = a[j];
// a[j] = temp;
// }
// printArray(a);
/**
* 思路3:相同的数组元素,不交换位置
* 如:数组{5,5,3} 以上述代码,交换两次
* 其实只交换一次就可以完成
*/
for (int j = 0; j <a.length-1; j++) {//四轮
int minIndex = j;
for (int i = j+1; i <a.length ; i++) {//比较
if(a[minIndex]>a[i]){
minIndex = i;
}
}
//不相等才交换位置,去除数组元素的不确定性对效率的影响
if(a[minIndex]!= a[j]){
//固定位置为j,minIndex为最小值的下标位置,那么最终是j和minIndex两个位置元素
int temp = a[minIndex];
a[minIndex] = a[j];
a[j] = temp;
}
}
printArray(a);
}
}
// 总结:把选择排序看成是冒泡排序的一种改进