上两篇博客我们讲过了插入排序和交换排序,这篇博客我们就来讲解一下算法的另一大分类——选择排序。
选择排序的基本思想是:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。
选择排序可以分为直接选择排序和堆排序。
咱们今天先说一下简单选择排序。它的基本流程是这样的:
(1)从待排序序列中,找到关键字最小的元素。
(2)如果第一个元素不是最小的,则将第一个元素与最小元素互换。
(3)从待排序的n-1个元素中重复步骤(1)和(2)直至排序结束。
例如:
初始关键字:45 38 66 90 88 10 25 45
第一次选择:10 [38 66 90 88 45 25 45]
第二次选择:10 25 [66 90 88 45 38 45]
第三次选择:10 25 38 [90 88 45 66 45]
第四次选择:10 25 38 45 [88 90 66 45]
第五次选择:10 25 38 45 45 [90 66 88]
第六次选择:10 25 38 45 45 66 [90 88]
第七次选择:10 25 38 45 45 66 88 90
简单排序的算法如下:
void SelectSort(List R, int n){
int min ,i,j;
//每次循环,选择出一个最小键值
for (i=1;i<=n-1;i++){
min=i; //假设第i个记录键值最小
//循环比较第i个记录与之后的记录
for (j=i+1;j<=n;j++){
//记录下最小的记录下标
if(R[j].key<R[min].key){
min=j;
}
if(min!=j){
//将最小键值与第i个记录交换
swap(R[min],R[j])
}
}
}
}
算法分析:
时间复杂度:
简单选择排序的比较次数与序列的初始排序无关。假设待排序的序列有 N 个元素,则比较次数总是N(N-1)/2。而移动次数与序列的初始排序有关。当序列正序时,移动次数最少,为0。当序列反序时,移动次数最多,为3N(N-1)/2。所以,综合以上,简单排序的时间复杂度为 O(N2)。
空间复杂度:
简单选择排序需要占用 1 个临时空间,在交换数值时使用。
综上:
下篇博客咱们再来讲另一种选择排序——堆排序。敬请期待。