选择排序算法详解
A. 把第一个元素(下标为i)当成最大值(从前往后排序)------降序
1.核心代码
for (int i = 0; i <numbers.length-1; i++) {
//从最大值为头部,就是降序
int max_index=i;
//前面往后面移动,所以j=i且j的循环判定条件无需-1
for (int j =i; j<numbers.length; j++) {
if(numbers[max_index]<numbers[j]){
max_index=j;
}
}
int temp=numbers[max_index];
numbers[max_index]=numbers[i];
numbers[i]=temp;
}
2.常见问题点分析
2.1 如何进行选择排序???
解决方案: 1.把第i个元素(从0开始)当成成最大值,此时max_index=i
2.拿该元素去与剩余的未确定顺序的元素比大小,找到最大值所在的下标
把所对应的下标赋值给max_index
3.拿最大值(下标为max_index)与第一个元素(下标为i)进行数据交换
此时循环遍历的范围就会少1(确定了一个数字的位置)
循环往复执行上述步骤,直至满足循环次数=数组长度-1,循环才结束
2.2 选择排序的循环次数为多少?
解决方案:循环次数=数组长度-1
2.3 选择排序具体操作(数字是这么移动的)过程
以数组int[] a=[-2,66,77,99,23]为列
排序次数 | 数组剩余部分(需要排序的) | 排序前的数组 | 排序后的数组 |
---|---|---|---|
第1次 | [-2,66,77,99,23] | [-2,66,77,99,23] | [99,66,77,-2,23] |
第2次 | [66,77,-2,23] | [99,66,77,-2,23] | [99,77,66,-2,23] |
第3次 | [66,-2,23] 注:66为最大值,无需交换 | [99,77,66,-2,23] | [99,77,66,-2,23] |
第4次 | [-2,23] | [99,77,66,-2,23] | [99,77,66,23,-2] |
2.4 第一个元素当成最大值这句话中的第一个元素指的是什么?
解决方案:此第一个元素意思是需要排序的数组的剩余部分的第一个位置的数据(见2.3)
2.5 为什么排序思路的第三步必须执行,无论是否找到最大值下标???
解答:只有两种情况,要么找到一个最大值下标,要么最大值下标就是第一个元素的位置
3.运行截图
4.源代码
public class SelectArray01{
public static void main(String[] args) {
System.out.println("选择排序(假设第一个元素为最大值,从前往后排序)");
int[] numbers={-2,66,77,99,23};
System.out.println("排序前");
for (int temp01:numbers
) {
System.out.print(temp01+"\t");
}
System.out.println();
for (int i = 0; i <numbers.length-1; i++) {
//从最大值为头部,就是降序
int max_index=i;
//前面往后面移动,所以j=i且j的循环判定条件无需-1
for (int j =i; j<numbers.length; j++) {
if(numbers[max_index]<numbers[j]){
max_index=j;
}
}
int temp=numbers[max_index];
numbers[max_index]=numbers[i];
numbers[i]=temp;
System.out.println("第"+(i+1)+"次排序后:");
for (int temp02:numbers
) {
System.out.print(temp02+"\t");
}
//保证每次排完序的结果输完后进行换行操作
System.out.println();
}
System.out.println("\n选择排序的结果为:");
for (int temp03:numbers
) {
System.out.print(temp03+"\t");
}
}
}
B. 把第一个元素(下标为i)当成最小值(从前往后排序)------升序
1.核心代码
for (int i = 0; i <numbers.length-1; i++) {
int min_index=i;
//寻找最小值的范围会随着i的增大而缩小,从而达到从前往后排序的目的
for (int k=i;k<numbers.length;k++){
if(numbers[min_index]>numbers[k]){
min_index=k;
}
}
int temp=numbers[min_index];
numbers[min_index]=numbers[i];
numbers[i]=temp;
}
2.常见问题点分析
2.1 如何进行选择排序???
解决方案: 1.把第i个元素(从0开始)当成成最小值,此时min_index=i;
2.拿该元素去与剩余的未确定的元素比大小,找到最小值所在的下标
把所对应的下标赋值给min_index
3.此时需要拿最小值(下标为min_index)与第1个元素(下标为i)
进行交换数据(任何情况都必须执行3步骤)
此时循环遍历的范围就会少1(确定了一个数字的位置)
循环往复执行上述步骤,直至满足循环次数=数组长度-1,循环才结束
2.2 此方法的出来的结果为啥是升序??
解答:因为每次都是找到数组中的最小值并且把它放到前面,数据的排列就是从小到大,所以结果为升序。
2.3 选择排序具体操作(数字是这么移动的)过程
以数组int[] a=[45,66,77,99,23,-2]为列
排序次数 | 数组剩余部分(需要排序的) | 排序前的数组 | 排序后的数组 |
---|---|---|---|
第1次 | [45,66,77,99,23,-2] | [45,66,77,99,23,-2] | [-2,66,77,99,23,45] |
第2次 | [66,77,99,23,45] | [-2,66,77,99,23,45] | [-2,23,77,99,66,45] |
第3次 | [77,99,66,45] | [-2,23,77,99,66,45] | [-2,23,45,99,66,77] |
第4次 | [99,66,77] | [-2,23,45,99,66,77] | [-2,23,45,66,99,77] |
第5次 | [99,77] | [-2,23,45,66,99,77] | [-2,23,45,66,77,99] |
2.4 第一个元素当成最小值这句话中的第一个元素指的是什么?
解决方案:此第一个元素意思是需要排序的数组的剩余部分的第一个位置的数据(见2.3)
2.5 为什么排序思路的第三步必须执行,无论是否找到最小值下标???
解答:只有两种情况,要么找到一个最小值下标,要么最小值下标就是第一个元素的位置
3.运行截图
4.源代码
public class SelectArray02 {
public static void main(String[] args) {
System.out.println("选择排序选择从头部开始交换");
int[] numbers={45,66,77,99,23,-2};
System.out.println("排序前");
for (int temp01:numbers
) {
System.out.print(temp01+"\t");
}
System.out.println();
for (int i = 0; i <numbers.length-1; i++) {
int min_index=i;
for (int k=i;k<numbers.length;k++){
if(numbers[min_index]>numbers[k]){
min_index=k;
}
}
int temp=numbers[min_index];
numbers[min_index]=numbers[i];
numbers[i]=temp;
System.out.println("第"+(i+1)+"次排序后:");
for (int temp02:numbers
) {
System.out.print(temp02+"\t");
}
System.out.println();
}
System.out.println("选择排序的最终结果为:");
for (int temp03:numbers
) {
System.out.print(temp03+"\t");
}
}
}
C. 把最后一个元素(下标为数组长度-1-i)当成最小值(从后往前排序)------降序
1.核心代码
for (int i = 0; i <numbers.length-1; i++) {
//每次把未排序的数组部分的最后一个位置的数据当成最小值,
//与前面的数字进行比较,如果遇到比它还小的数字,就进行交换操作
int min_index=numbers.length-1-i;
//找最小值的下标,最小值只可能比它小
for (int p = 0; p <numbers.length-i-1; p++) {
if(numbers[min_index]>numbers[p]){
min_index=p;
}
}
int temp=numbers[min_index];
numbers[min_index]=numbers[numbers.length-1-i];
numbers[numbers.length-1-i]=temp;
}
2.常见问题点分析
2.1 如何进行选择排序
解决方案: 1.把第最后一个元素(从数组长度-1-i开始)当成最小值,此时min_index=数据长度-1-i;
2.拿该元素去与剩余的未确定的元素比大小,找到最小值后,把所对应的下标赋值给min_index
3.拿最小值(下标为min_index)与最后1个位置(下标为数组长度-1-i)的数据
进行交换(数据的交换)
此时循环遍历的范围就会少1(确定了一个数字的位置)
循环往复执行上述步骤,直至满足循环次数=数组长度-1,循环才结束
2.2 选择排序具体操作(数字是这么移动的)过程
以数组int[] a=[-1,3,-8,5,2,127]为列
排序次数 | 数组剩余部分(需要排序的) | 排序前的数组 | 排序后的数组 |
---|---|---|---|
第1次 | [-1,3,-8,5,2,127] | [-1,3,-8,5,2,127] | [-1,3,127,5,2,-8] |
第2次 | [-1,3,127,5,2] | [-1,3,127,5,2,-8] | [2,3,127,5,-1,-8] |
第3次 | [2,3,127,5] | [2,3,127,5,-1,-8] | [5,3,127,2,-1,-8] |
第4次 | [5,3,127] | [5,3,127,2,-1,-8] | [5,127,3,2,-1,-8] |
第5次 | [5,127] | [5,127,3,2,-1,-8] | [127,5,3,2,-1,-8] |
2.3 最后一个元素(下标为数组长度-1-i)当成最小值中的最后一个元素指的是什么???
解答:未排序部分数组(数组的剩余部分)中的最后一个位置
2.4 为什么排序思路的第三步必须执行,无论是否找到最小值下标???
解答:只有两种情况,要么找到一个最小值下标,要么最小值下标就是最后一个元素的位置
3.运行截图
4.源代码
public class SelectArray03 {
public static void main(String[] args) {
//把最后一个位置的数当成最小值,如果它不是最小值,就要换成最小的
System.out.println("选择排序从尾部开始交换(从后往前)");
int[] numbers={-1,3,-8,5,2,127};
System.out.println("排序前");
for (int temp01:numbers
) {
System.out.print(temp01+"\t");
}
System.out.println();
for (int i = 0; i <numbers.length-1; i++) {
//每次把未排序的数组部分的最后一个当成最小值,与前面的数字进行比较,如果遇到比它还小的数字,就
int min_index=numbers.length-1-i;
//找最小值的下标,最小值只可能比它小
for (int p = 0; p <numbers.length-i-1; p++) {
if(numbers[min_index]>numbers[p]){
min_index=p;
}
}
int temp=numbers[min_index];
numbers[min_index]=numbers[numbers.length-1-i];
numbers[numbers.length-1-i]=temp;
System.out.println("第"+(i+1)+"次排序后:");
for (int temp02:numbers
) {
System.out.print(temp02+"\t");
}
System.out.println();
}
System.out.println("选择排序结束后的结果如下所示:");
for (int temp03:numbers
) {
System.out.print(temp03+"\t");
}
}
}
D. 把最后一个元素(下标为数组长度-1-i)当成最大值(从后往前排序)------升序
1.核心代码
for (int i = 0; i <numbers.length-1; i++) {
//升序,采用最大值
int max_index=numbers.length-1-i;
//找到最大值下标,每确定一次,比较次数-1
for (int j = 0; j <numbers.length-1-i; j++) {
if(numbers[max_index]<numbers[j]){
max_index=j;
}
}
int temp=numbers[max_index];
numbers[max_index]=numbers[numbers.length-1-i];
numbers[numbers.length-1-i]=temp;
}
2.常见问题点分析
2.1 如何进行选择排序???
解决方案: 1.把第最后一个元素(从数组长度-1-i开始)当成最大值,此时max_index=数据长度-1-i;
2.拿该元素去与剩余的未确定的元素比大小,找到最小值所在的下标并赋值给max_index
3.拿最大值(下标为max_index)与最后1个位置(下标为数组长度-1-i)的数据
进行交换(数据的交换)
此时循环遍历的范围就会少1(确定了一个数字的位置)
循环往复执行上述步骤,直至满足循环次数=数组长度-1,循环才结束
2.2 选择排序具体操作(数字是这么移动的)过程
以数组int[] a=[1,66,-5,5,33]为列
排序次数 | 数组剩余部分(需要排序的) | 排序前的数组 | 排序后的数组 |
---|---|---|---|
第1次 | [1,66,-5,5,33] | [1,66,-5,5,33] | [1,33,-5,5,66] |
第2次 | [1,33,-5,5] | [1,33,-5,5,66] | [1,5,-5,33,66] |
第3次 | [1,5,-5] | [1,5,-5,33,66] | [1,-5,5,33,66] |
第4次 | [1,-5] | [1,-5,5,33,66] | [-5,1,5,33,66] |
2.3 最后一个元素(下标为数组长度-1-i)当成最大值中的最后一个元素指的是什么???
解答:未排序部分数组(数组的剩余部分)中的最后一个位置(粗略理解为相对位置,每次位置均不一样)
2.4 为什么排序思路的第三步必须执行,无论是否找到最大值下标???
解答:只有两种情况,要么找到一个最大值下标,要么最大值下标就是最后一个元素的位置(即初始化赋值的那个值)
3.运行截图
4.源代码
public class SelectArray04 {
public static void main(String[] args) {
System.out.println("选择排序--找最大值或最小值");
int[] numbers={1,66,-5,5,33};
System.out.println("排序前");
for (int temp01:numbers
) {
System.out.print(temp01+"\t");
}
System.out.println();
for (int i = 0; i <numbers.length-1; i++) {
//升序,采用最大值
int max_index=numbers.length-1-i;
//找到最大值下标,每确定一次,比较次数-1
for (int j = 0; j <numbers.length-1-i; j++) {
if(numbers[max_index]<numbers[j]){
max_index=j;
}
}
int temp=numbers[max_index];
numbers[max_index]=numbers[numbers.length-1-i];
numbers[numbers.length-1-i]=temp;
System.out.println("第"+(i+1)+"次排序后:");
for (int temp02:numbers
) {
System.out.print(temp02+"\t");
}
System.out.println();
}
System.out.println("选择排序(把最后一个位置的数字当成最大值)结束后的结果如下所示:");
for (int temp03:numbers
) {
System.out.print(temp03+"\t");
}
}
}