首先在未排序序列中找到最小的(升序)元素,放在未排序序列的起始位置,然后再从剩下的未排序序列中找到最小的(升序)元素,放在未排序序列的起始位置,以此类推。
void SelectSort(int* a, int n){
for(int i = 0; i < n - 1; i++){
//在未排序序列中找最小的元素
int minIndex = i;
for(int j = i + 1; j < n; j++){
if(a[minIndex] > a[j]){
minIndex = j;//minIndex始终是最小元素的下标
}
}
Swap(&a[minIndex], &a[i]);//将最小元素和首元素交换
}
}
上面的是每次循环只找一个最小的,将最小的放首位后,序列向右收缩;
而现在的升级版本是每次循环找一个最小的和一个最大的,将最小的放首位,最大的放末位,序列向中间收缩。
然后
void SelectSort(int* a, int n){
int left = 0;
int right = n - 1;
while(left < right){
int minIndex = left;
int maxIndex = left;
for(int i = left + 1; i <= right; i++){
if(a[minIndex] > a[i]){
minIndex = i;
}
if(a[maxIndex < a[i]]){
maxIndex = i;
}
}
Swap(&a[minIndex], &a[left]);
if(maxIndex == left){
maxIndex = minIndex;
}
Swap(&a[maxIndex], &a[right]);
left++;
right--;
}
}
时间复杂度
假设有N个数据
不论数据是否有序,在排第1个数据时必定会比较N-1次,排第2个数据时必定会比较N-2次,所以总的比较次数为 1 + 2 + 3 + . . . + ( N − 1 ) 1 + 2 + 3+...+(N-1) 1+2+3+...+(N−1),等差数列求和,结果为 N 2 / 2 N^{2}/2 N2/2,时间复杂度为 O ( N 2 ) O(N^{2}) O(N2)。
空间复杂度
仅仅使用了常数个辅助单元,空间复杂度是O(1);
稳定性
举个例子,序列6 8 6 2 7, 第一遍选择,第一个6会和2交换,那么原序列中2个6的相对前后顺序就被破坏了,
所以是不稳定的。