开门见山,本文讲述一下选择排序的原理,后附代码:
1:什么是选择排序?
选择排序,重在选择二字,拿出来与冒泡排序对比下,可能更好地理解这个选择排序的处理逻辑。
在冒泡排序中,每一趟都要保证排序序列中的最大数字,到整个数列的一端,比如说按照升序排序的话,最大数字会跑到整个数列的最右边;而冒泡排序每一趟是怎么做才达到目标的呢?交换,从待排序列的最左端一直交换,如此,最大值就交换到了最右边;循环往复,排序效果完成。
这里,重点在于交换。
好,那么,这种交换是不是必要的呢?
仔细思考下交换的目的,是为了最终能够把最大的数据交换到最后;但实际上,为了达到这个目标,并不一定需要不断交换,可以考量的思路是,从左向右一直比较,把最小或者最大数字的索引记录下来,然后把这个索引所对应的值与最左边或者最右边的值进行一下交换,这样,是不是也达到了相同的目标?
仔细思考十秒钟。
的确如此,如果我们在比较的过程中,只是进行比较,而不涉及交换操作,这个效率毫无疑问要比冒泡排序高一些,但实际上依旧属于交换类算法;因为其做法相当于是从一堆数中找到最小或者最大的数,是个选择操作,所以,称为选择排序。
这里,重点在于比较记录索引,不进行交换。
是不是通俗易懂?这就是选择排序的基本原理和思想。
下面附上代码:
public class SelectSorting {
public static void main(String[] args) {
int[] array = new int[] { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10, 13, 15, 11 };
selectSort(array);
for (int ele : array) {
System.out.print(ele + " ");
}
}
/**
* @description
* @param array
*/
public static void selectSort(int[] array) {
// 重在于找到最大值的位置
int len = array.length;
for (int i = len - 1; i >= 0; i--) {
// 先定义索引为0
int index = 0;
int max = array[index];
// 接下来的循环很关键,重在于保留最大值的索引位置
for (int j = 0; j <= i; j++) {
if (max < array[j]) {
max = array[j];
index = j;
}
}
// 接下来的代码负责处理索引处的值与最右端值的交换
int temp = array[i];
array[i] = array[index];
array[index] = temp;
}
}
}
建议:多种排序算法最好参照着学习,弄清楚彼此之间的区别,这样会理解的快一些。
总结一下与冒泡排序的区别:
1:相同点,每一趟排序的目标,都是找到一个元素的位置,最大或者最小元素的最终位置。
2:不同点,达到目标的方式不同:冒泡排序不断交换来完成,一趟排序可能要多次交换;而选择排序则是通过比较来定位索引,然后做一次交换;
复杂度分析:
- 时间复杂度分析:可以参照以上代码,平均复杂度为O(N2);
- 空间复杂度,其中需要做一次交换,所以空间复杂度为O(1);