选择排序(Selection sort)
重复的扫描待排序序列,每次从待排序序列中选择最大(或最小)的元素放在已排序序列的末尾,直到序列整体有序。
基本思路(升序排序)
- 选择第1个元素作为有序序列(只有1个元素的序列必定有序)的尾元素
- 遍历后续所有元素,选择最小的元素和有序序列尾元素交换
- 继续选择第2个元素作为有序序列的尾元素,重复步骤2
- 直到序列整体有序为止
过程模拟
代码参考
void selectionSort(int a[],int n){//待排序数组a,数组长度n
for(int i=0;i<n-1;i++){
int minIndex=i;//假定最小值的下标
for(int j=i+1;j<n;j++){
//发现更小的值,记录下标
if(a[j]<a[minIndex]){
minIndex=j;
}
}
if(minIndex!=i)
swap(a[i],a[minIndex]);
}
}
复杂度
时间复杂度:O(n^2),共进行n-1轮比较,每轮比较的n-i-1次,但选择排序过程中需要交换的次数较少,因此效率略高于冒泡排序
空间复杂度:O(1),需要1个临时变量记录最小值的下标
稳定性
不稳定,因为存在前后元素的交换,多个相同位置排序前后的相对位置可能发生改变。
假定序列:2 2 5 1 3 4
第一次:1 2 5 2 3 4 (原本在前面的2和1交换位置,移到了后面)
第二次:1 2 5 2 3 4 (不需要交换)
第三次:1 2 2 5 3 4 (后面的2和5交换,最终排序后,两个“2”的相对位置发生改变)
特点
- 就地排序,不需要额外的存储空间
- 在比较排序算法中,数据移动次数少,比较次数多