选择排序的C实现
原理分析
- 将数组分成左右两部分,左边为已排序部分,右边是未排序部分(当然,这个左右之间的边界是会随着循环的进行而变化的)
与先前的插入排序不同的在于,左边部分是已经不会再发生替换的,即最终结果。
- 使用一个min指针(代表此数为最小)指向未排序的第一个元素作初始,遍历其后所有元素(即未排序部分),遇到比它小的数则min指针改为指向该数。
- 直到未排序部分全部比较完成,min指向最小数为止,就将min指向的元素与未排序部分的第一个元素进行交换。至此,完成一次排序。
实现思路
外层循环:i指向待排序的第一个元素,即本次循环的待排元素,依次递增,只需要循环到n-1的位置即可。
内层循环:j指向i+1的元素,即将此次i元素与后面所有元素进行比较,依次递增,需循环到最后一个元素。
实现代码
#include<stdio.h>
//按顺序输出数组元素
void trace(int A[],int N){
int i;
for(i= 0;i < N;i++){
if(i >0)printf(" ");//在相邻元素之间输入空格
printf("%d",A[i]);
}
printf("\n");
}
//交换元素
void Swap(int *a,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
/*
A为要排序的数组,N为数组长度
*/
void SelectionSort(int A[],int n){
int i,j,min;
for(i = 0;i<n-1;i++){
min = i;
//找i元素后的最小元素
for(j = i+1;j<n;j++){
if(A[j] < A[min]){
min = j;
}
}
Swap(&A[i],&A[min]);
trace(A,n);
}
}
int main(){
int n,i;
int A[100];
scanf("%d",&n);
for(i = 0;i<=n;i++)scanf("%d",&A[i]);
trace(A,n);
SelectionSort(A,n);
return 0;
}
时间复杂度分析
若数组长度为N,则观察代码可看出,每一次i循环都要将后面的所有数遍历比较一遍,所以无论在何种情况下,选择排序都需进行(N-1)+(N-2)+(N-3)+…+1=(N²-N)/2次比较运算,用于搜索右半未排序部分的最小值,忽略常数项,选择排序的时间复杂度为O(N²)。