【视频+图文+动画】详解选择排序(轻松易理解系列)
一、视频讲解选择排序
二、选择排序的思想
思想:(注:n为数组长度)
第一次交换中:
- 假定最小数是arr[0]
- 从arr[1]-arr[n-1]找最小值与arr[0]交换。
- 交换过后arr[0]位置上的数确定
第二次交换中:
- 假定最小数是arr[1],
- 从arr[2]-arr[n-1]找最小值与arr[1]交换。
- 交换过后arr[1]位置上的数确定
以此类推......
三、选择排序的动画演示及思路分析
动画演示:
- 粉色的数字:假定的最小值,
- 绿色的数字:需与假定最小值比较的数,
- 橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
思路分析:
以7,3,22,15,8为例:n为数组长度
1.第一次交换:3的位置被固定
- 粉色的数字:假定的最小值,
- 绿色的数字:需与假定最小值比较的数,
- 橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)假定最小数是arr[0]即min=arr[0]=7
(2) 从arr[1]-arr[n-1]找最小值(即从【3,22,15,8】找最小值)与arr[0]交换。
min=7和arr[1]=3比较: 若min>arr[1],min=arr[1],进行下一次比较
- 因为7>3
- 所以min=arr[1]=3
- 进行下一次比较
7 3 22 15 8 ⇒7 3 22 15 8
min=3和arr[2]=22比较:若min>arr[2],min=arr[2],进行下一次比较
- 因为3<22
- 所以min=arr[1]=3
- 进行下一次比较
7 3 22 15 8 ⇒7 3 22 15 8
min=3和arr[3]=15比较:若min>arr[3],min=arr[3],进行下一次比较
- 因为3<15
- 所以min=arr[1]=3
- 进行下一次比较
7 3 22 15 8 ⇒7 3 22 15 8
min=3和arr[4]=8比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为3<8
- 所以min=arr[1]=3
7 3 22 15 8 ⇒7 3 22 15 8
此时找到了【3,22,15,8】中的最小值:3
所以arr[0]=7和arr[1]=3交换位置
(3)交换过后arr[0]=3位置上的数确定:7 3 22 15 8 ⇒ 3 7 22 15 8
2.第二次交换:7的位置被固定
-
粉色的数字:假定的最小值,
-
绿色的数字:需与假定最小值比较的数,
-
橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)假定最小数是arr[1]即min=arr[1]=7
(2) 从arr[2]-arr[n-1]找最小值(即从【22,15,8】找最小值)与arr[1]交换。
min=7和arr[2]=22比较:若min>arr[2],min=arr[2],进行下一次比较
- 因为7<22
- 所以min=arr[1]=7
- 进行下一次比较
3 7 22 15 8 ⇒ 3 7 22 15 8
min=7和arr[3]=15比较:若min>arr[3],min=arr[3],进行下一次比较
- 因为7<15
- 所以min=arr[1]=7
- 进行下一次比较
3 7 22 15 8 ⇒ 3 7 22 15 8
min=3和arr[4]=8比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为3<8
- 所以min=arr[1]=3
3 7 22 15 8 ⇒ 3 7 22 15 8
此时因为 【22,15,8】 中的数都大于 min=arr[1]=7
所以最小值:min=arr[1]=7
(3)本轮不发生交换 arr[1]=7位置上的数确定:3 7 22 15 8⇒ 3 7 22 15 8
3.第三次交换:8的位置被固定
-
粉色的数字:假定的最小值,
-
绿色的数字:需与假定最小值比较的数,
-
橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)假定最小数是arr[2]即min=arr[2]=22
(2) 从arr[3]-arr[n-1]找最小值(即从【15,8】找最小值)与arr[2]交换。
min=22和arr[3]=15比较:若min>arr[3],min=arr[3],进行下一次比较
- 因为22>15
- 所以min=arr[3]=15
- 进行下一次比较
3 7 22 15 8 ⇒ 3 7 22 15 8
min=15和arr[4]=8比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为15>8
- 所以min=arr[4]=8
3 7 22 15 8 ⇒ 3 7 22 15 8
此时找到了【22,15,8】中的最小值:8
所以arr[2]=22和arr[4]=8交换位置
(3)交换过后arr[2]=8位置上的数确定: 3 7 22 15 8⇒ 3 7 8 15 22
4.第四次交换:15的位置被固定
-
粉色的数字:假定的最小值,
-
绿色的数字:需与假定最小值比较的数,
-
橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)假定最小数是arr[3]即min=arr[3]=15
(2) 从arr[4]-arr[n-1]找最小值(即从【22】找最小值)与arr[3]交换。
min=15和arr[4]=22比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为15<22
- 所以min=arr[3]=15
3 7 8 15 22 ⇒ 3 7 8 15 22
此时因为 【22】 大于 min=arr[3]=15
所以最小值:min=arr[3]=15
(3)本轮不发生交换 arr[3]=15位置上的数确定:3 7 8 15 22⇒ 3 7 8 15 22
四、选择排序的代码+代码优化+代码详解
代码--————多个for循环分别控制排序:
package Sort;
import java.util.Arrays;
public class SelectionSort {
// 7,3,22,15,8
public static void main(String[] args) {
int arr[] = { 7, 3, 22, 15, 8 };
int min = 0;// 假定最小值
int minIndex = 0;// 假定最小值的下标
int j = 0;
//第一次排序
min=arr[0];//假定最小值为7
minIndex=0;//假定最小值的下标为0
for(j=0+1;j<arr.length;j++) {//从3 22 15 8 中找比7小的数,找到就把这个数变成假定最小值
if(min>arr[j]) {//假定最小值需要替换
min=arr[j];//将假定最小值换为arr[j]
minIndex=j;//将假定最小值下标换为j
}
}
if(minIndex!=0) {//需要交换,就像这里的7和3
arr[minIndex]=arr[0];
arr[0]=min;
}
System.out.println(Arrays.toString(arr));
//第二次排序
min=arr[1];//假定最小值为7
minIndex=1;//假定最小值的下标为1
for(j=1+1;j<arr.length;j++) {//从 22 15 8 中找比7小的数,找到就把这个数变成假定最小值
if(min>arr[j]) {//假定最小值需要替换
min=arr[j];//将假定最小值换为arr[j]
minIndex=j;//将假定最小值下标换为j
}
}
if(minIndex!=1) {//不需要交换,7<22,15,8
arr[minIndex]=arr[1];
arr[1]=min;
}
System.out.println(Arrays.toString(arr));
//第三次排序
min=arr[2];//假定最小值为22
minIndex=2;//假定最小值的下标为2
for(j=1+2;j<arr.length;j++) {//从 15 8 中找比22小的数,找到就把这个数变成假定最小值
if(min>arr[j]) {//假定最小值需要替换
min=arr[j];//将假定最小值换为arr[j]
minIndex=j;//将假定最小值下标换为j
}
}
if(minIndex!=2) {//需要交换,就像这里的22和8
arr[minIndex]=arr[2];
arr[2]=min;
}
System.out.println(Arrays.toString(arr));
//第四次排序
min=arr[3];//假定最小值为15
minIndex=3;//假定最小值的下标为3
for(j=1+3;j<arr.length;j++) {//22 中找比15小的数,找到就把这个数变成假定最小值
if(min>arr[j]) {//假定最小值需要替换
min=arr[j];//将假定最小值换为arr[j]
minIndex=j;//将假定最小值下标换为j
}
}
if(minIndex!=3) {//不需要交换,15<22
arr[minIndex]=arr[3];
arr[3]=min;
}
System.out.println(Arrays.toString(arr));
}
}
结果:
优化代码--————两个for循环嵌套控制排序:
优化分析:
由下表可以看出:
- 我们可以再用一个for循环
- 嵌套在原有的for循环外,来循环表格中红色数字部分
- 此循环范围是【0-3】
假定最小值 | 与假定最小值比较的范围 | |
---|---|---|
第一次交换 | arr[0]=7 | arr[0+1]-arr[4] |
第二次交换 | arr[1]=7 | arr[1+1]-arr[4] |
第三次交换 | arr[2]=22 | arr[2+1]-arr[4] |
第四次交换 | arr[3]=15 | arr[3+1] |
代码:
package Sort;
import java.util.Arrays;
public class SelectionSort {
// 7,3,22,15,8
public static void main(String[] args) {
int arr[] = { 7, 3, 22, 15, 8 };
int min = 0;// 假定最小值
int minIndex = 0;// 假定最小值的下标
int j = 0;
int i = 0;
for (i = 0; i < arr.length - 1; i++) {//控制需与假定最小值比较的数的范围
min = arr[i];// 第一次:(1)假定最小值为7
minIndex = i;// 第一次:(1)假定最小值的下标为0
for (j = i + 1; j < arr.length; j++) {//第一次:(1) 从3 22 15 8 中找比7小的数,找到就把这个数变成假定最小值
if (min > arr[j]) {// 假定最小值需要替换
min = arr[j];// 将假定最小值换为arr[j]
minIndex = j;// 将假定最小值下标换为j
}
}
if (minIndex != i) {// 第一次:(1)需要交换,就像这里的7和3
arr[minIndex] = arr[i];
arr[i] = min;
}
System.out.println(Arrays.toString(arr));
}
}
}
结果:
代码详解(优化版本)
以7,3,22,15,8为例:n为数组长度
1.第一次交换:3的位置被固定
- 粉色的数字:假定的最小值,
- 绿色的数字:需与假定最小值比较的数,
- 橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)
- 假定最小数是arr[0]即min=arr[0]=7
- i=0,minIndex=0,j=0+1
(2) 从arr[1]-arr[n-1]找最小值(即从【3,22,15,8】找最小值)与arr[0]交换。
min=7和arr[1]=3比较: 若min>arr[1],min=arr[1],进行下一次比较
- 因为7>3
- 所以min=arr[1]=3
- i=0,minIndex=1
- 进行下一次比较
7 3 22 15 8 ⇒7 3 22 15 8
min=3和arr[2]=22比较:若min>arr[2],min=arr[2],进行下一次比较
- 因为3<22
- 所以min=arr[1]=3
- i=0,minIndex=1
- 进行下一次比较
7 3 22 15 8 ⇒7 3 22 15 8
min=3和arr[3]=15比较:若min>arr[3],min=arr[3],进行下一次比较
- 因为3<15
- 所以min=arr[1]=3
- i=0,minIndex=1
- 进行下一次比较
7 3 22 15 8 ⇒7 3 22 15 8
min=3和arr[4]=8比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为3<8
- 所以min=arr[1]=3
- i=0,minIndex=1
7 3 22 15 8 ⇒7 3 22 15 8
(3)
-
因为i=0,minIndex=1, i ! = minIndex
-
进入if条件分支语句
if (minIndex != i) {// 第一次:(1)需要交换,就像这里的7和3
arr[minIndex] = arr[i];
arr[i] = min;
}
所以arr[0]=7和arr[1]=3交换位置
(4)交换过后arr[0]=3位置上的数确定:7 3 22 15 8 ⇒ 3 7 22 15 8
2.第二次交换:7的位置被固定
-
粉色的数字:假定的最小值,
-
绿色的数字:需与假定最小值比较的数,
-
橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)
- 假定最小数是arr[1]即min=arr[1]=7
- -i=1,minIndex=1,j=1+1
(2) 从arr[2]-arr[n-1]找最小值(即从【22,15,8】找最小值)与arr[1]交换。
min=7和arr[2]=22比较:若min>arr[2],min=arr[2],进行下一次比较
- 因为7<22
- 所以min=arr[1]=7
- i=1,minIndex=1
- 进行下一次比较
3 7 22 15 8 ⇒ 3 7 22 15 8
min=7和arr[3]=15比较:若min>arr[3],min=arr[3],进行下一次比较
- 因为7<15
- 所以min=arr[1]=7
- i=1,minIndex=1
- 进行下一次比较
3 7 22 15 8 ⇒ 3 7 22 15 8
min=3和arr[4]=8比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为3<8
- 所以min=arr[1]=3
- i=1,minIndex=1
3 7 22 15 8 ⇒ 3 7 22 15 8
(3)
-
因为i=1,minIndex=1, i == minIndex
-
不进入if条件分支语句
-
所以最小值:min=arr[1]=7
(4)本轮不发生交换 arr[1]=7位置上的数确定:3 7 22 15 8⇒ 3 7 22 15 8
3.第三次交换:8的位置被固定
-
粉色的数字:假定的最小值,
-
绿色的数字:需与假定最小值比较的数,
-
橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)
- 假定最小数是arr[2]即min=arr[2]=22
- i=2,minIndex=2 j=2+1
(2) 从arr[3]-arr[n-1]找最小值(即从【15,8】找最小值)与arr[2]交换。
min=22和arr[3]=15比较:若min>arr[3],min=arr[3],进行下一次比较
- 因为22>15
- 所以min=arr[3]=15
- i=2,minIndex=3
- 进行下一次比较
3 7 22 15 8 ⇒ 3 7 22 15 8
min=15和arr[4]=8比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为15>8
- 所以min=arr[4]=8
- i=2,minIndex=4
3 7 22 15 8 ⇒ 3 7 22 15 8
(3)
-
因为i=2,minIndex=4, i ! = minIndex
-
进入if条件分支语句
if (minIndex != i) {// 第一次:(1)需要交换,就像这里的7和3
arr[minIndex] = arr[i];
arr[i] = min;
}
所以arr[2]=22和arr[4]=8交换位置
(3)交换过后arr[2]=8位置上的数确定: 3 7 22 15 8⇒ 3 7 8 15 22
4.第四次交换:15的位置被固定
-
粉色的数字:假定的最小值,
-
绿色的数字:需与假定最小值比较的数,
-
橘色的数字:位置固定的数字【位置一旦固定,不参与下次排序】
(1)
- 假定最小数是arr[3]即min=arr[3]=15
- i=3,minIndex=3 ,j=3+1
(2) 从arr[4]-arr[n-1]找最小值(即从【22】找最小值)与arr[3]交换。
min=15和arr[4]=22比较: 若min>arr[4],min=arr[4],结束第一轮比较
- 因为15<22
- 所以min=arr[3]=15
- i=3,minIndex=3
3 7 8 15 22 ⇒ 3 7 8 15 22
(3)
-
因为i=3,minIndex=3, i == minIndex
-
不进入if条件分支语句
所以最小值:min=arr[3]=15
(3)本轮不发生交换 arr[3]=15位置上的数确定:3 7 8 15 22⇒ 3 7 8 15 22
到此选择排序讲解完啦~~
欢迎大家来公号 “小乔的编程内容分享站” 来找小乔玩~
一起学习Java基础+算法~
还有更多资源等你来拿哦~