算法的基本思想,是从无序中选择最小的元素,然后交换。
2、从无序数组中选取最小的元素和有序数组的最后一个元素交换。
3、重复第2步,直到无序数组没有元素为止。
选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
第0次排序:
{1},{4 2 5 3 7 6}
第1次排序:
{1 2},{4 5 3 7 6}
第2次排序:
{1 2 3},{5 4 7 6}
第3次排序:
{1 2 3 4},{5 7 6}
第4次排序:
{1 2 3 4 5},{7 6}
第5次排序:
{1 2 3 4 5 6},{7}
根据以上排序过程可以看到,只需要n-1次排序,所有元素就全部排好序了。
算法描述
1、从数组的第一个元素开始,将待排序数组分为有序和无序两个区间。2、从无序数组中选取最小的元素和有序数组的最后一个元素交换。
3、重复第2步,直到无序数组没有元素为止。
复杂度和稳定性
时间复杂度为O(n*n),空间复杂度为O(1)。选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
模拟排序过程
以数据6,4,2,5,3,7,1为例,排序结果为从小到大。第0次排序:
{1},{4 2 5 3 7 6}
第1次排序:
{1 2},{4 5 3 7 6}
第2次排序:
{1 2 3},{5 4 7 6}
第3次排序:
{1 2 3 4},{5 7 6}
第4次排序:
{1 2 3 4 5},{7 6}
第5次排序:
{1 2 3 4 5 6},{7}
根据以上排序过程可以看到,只需要n-1次排序,所有元素就全部排好序了。
核心代码
private static void selectSort(int[] array) {
int len = array.length;
int i = 0;
while (i < len-1) {
int temp = i;
for (int j = i+1; j < len; j++) {
if (array[j] < array[temp]) {
temp = j;
}
}
swap(array, i, temp);
i++;
}
}
完整代码
public class Sort {
private static void selectSort(int[] array) {
int len = array.length;
int i = 0;
while (i < len-1) {
System.out.println("第"+i+"次排序:");
int temp = i;
for (int j = i+1; j < len; j++) {
if (array[j] < array[temp]) {
temp = j;
}
}
swap(array, i, temp);
printf(array);
i++;
}
}
private static void swap(int[] array, int a, int b) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
private static void printf(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int array[] = { 6, 4, 2, 5, 3, 7, 1 };
selectSort(array);
printf(array);
}
}