大家有没有类似的感觉?无论是面试还是笔试,提起选择排序大家都觉得很简单,但是再具体写代码的时候会出现各种各样的问题:
比如,外层循环的边界条件总是写错;内存循环中无序区间的长度是不断变化的,如何准确控制?
本文就来给大家解决这些痛点,并且让大家过目不忘。(
代码是java写的)
把待排序的数组划分成有序区间和无序区间,从无序区间中找到最大的数,放到无序区间的最后一位;
划分有序区间和无序区间,开始无序区间的数组长度为整个数组的长度array.length,无序区间的数组长度为0。
(1)max=0,指向无序区间第一个数,j=1,指向无序区间第二个数
(2)比较j和max指向的数,如果max指向的数小于j指向的数,则max=j;j不断右移,进行比较操作,直到无序区间最后一个数,最后结果如下:
(3)交换max指向的数据和无序区间的最后一个数,结果如下:
此时整个无序区间中最大的数到了无序区间的最后一位,
无序区间的长度减少1,有序区间的长度增加1;
不断循环进行以上操作,直到整个数组有序,并且在整个循环当中,每循环一次无序区间的长度减1,有序区间的长度加1
那么问题来了,要循环多少次以上操作?并且无序区间的长度是动态变化的,如何去控制;
循环好写,但是边界条件不好定,这也是为什么我们在LeetCode上每次写题,思路貌似很清晰,代码也感觉很好写,但是写完已提交,总是无法通过,归根结底,没有解决痛点。
1,要循环多少次以上操作?(决定最外层循环控制次数)
所以总共进行整个数组的长度减1次比较,即array.length-1次。
为什么最后一次无序区间长度为2而不是1?
因为两个数比较一次就可以决定其次序。
for (int i = 0; i < array.length-1 ; i++){
}
i为控制最外层循环的变量,从0开始。j为内层无序区间下标控制变量,从1开始(为什么从1开始,上文有讲解)。每循环一次i增加1,而无序区间的长度就减少1,可用array.length-i进行控制,控制内层循环代码如下:
for (int j = 1; j <array.length-i ; j++){
}
这样就能动态表示外层每循环一次,无序区间长度的变化过程,从array.length,array.length-1,......直到2;
public void selectSort(int[] array){
for (int i = 0; i < array.length-1 ; i++) {
int max=0;
for (int j = 1; j <array.length-i ; j++) {
if(array[max]<array[j]){
max=j;
}
}
int temp=array[max];
array[max]=array[array.length-i-1];
array[array.length-i-1]=temp;
}
}
选择排序的时间复杂度为O(n*n),空间复杂度为O(1)。
如果还有不清楚的地方,
欢迎大家关注B站,码农一饭,有视频讲解哦