选择排序法可使用两种方式排序:从小到大或从大到小;例如:当N个数据需要由大至小排序时,首先将第一个位置的数据依次和第2、3、4……、N个位置的数据进行比较。如果数据大于或等于其中一个位置,则不变;若小于其中一个位置的数据,则两个位置的数据互换。互换后第1个位置的数据继续与后续位置的数据进行比较,直到位置最末端,此时第一个位置的数据即为此排序数组的最大值。接下来选择第二个位置的数据,依次与第3、4……、N个位置的数据进行比较,将最大值放入第二个位置。此循环方法直到N-1个位置的最大值找到后即可完成选择排序法由大到小的排列。下面仍然利用数组6、4、9、8、3的由小到大排序过程来说明选择排序法的演算方式。
原始数据:6、4、9、8、3
第一次扫描:先找到这个数组中的最小值,与第一个元素进行交换;
第一次扫描过程:第一个位置的数据与第2、3、4、5个位置的数据依次比较,如果第一个位置的数据小于等于其中一个位置的数据,则不变;若大于其中一个位置的数据则交换位置;则6与4比较,6>4,交换位置得4、6、9、8、3;因为第一个位置的数据发生了变化,因此,再次将第一个位置的数据与第3、4、5个位置的数据比较:4比9和8都小,因此不用交换位置,而4比3小,交换位置为:3、6、9、8、4
因此第一次扫描结果:3、6、9、8、4;
第二次扫描:先找到这个数组(除第一个元素外)中的最小值,与第二个元素进行交换;
第二次扫描过程:将第二个位置的数据与第3、4、5个位置的数据依次比较,如果第二个位置的数据小于等于其中一个位置的数据,则不变;若大于其中一个位置的数据则交换位置;则6与9、8比较,不交换位置,而6与4比较交换位置得3、4、9、8、6
因此第二次扫描结果:3、4、9、8、6
第三次扫描:先找到这个数组(除第一、二个元素外)中的最小值,与第三个元素进行交换;
第三次扫描过程:将第三个位置的数据与第4、5个位置的数据依次比较,如果第三个位置的数据小于等于其中一个位置的数据,则不变;若大于其中一个位置的数据则交换位置;则9与8比较,交换位置得:3、4、8、9、6;然后8再与6比较,交换位置得3、4、6、9、8
因此第三次扫描结果:3、4、6、9、8
第四次扫描:先找到这个数组(除第一、二、三个元素外)中的最小值,与第四个元素进行交换;
第四次扫描过程:将第四个位置的数据与第5个位置的数据进行比较,若小于第5个位置的数据则进行交换,否则不交换,因为9<8,则交换位置得:3、4、6、8、9
因此最终选择排序的结果为:3、4、6、8、9
对选择排序法的分析如下:
1、无论是最坏情况、最佳情况及平均情况都需要找到最大值(或最小值),因此比较次数为:(n-1)+(n-2)+……+1=n*(n-1)/2次,时间复杂度为O(n^2);
2、由于选择排序是每次求出未排序数组中的最大或最小值与该数组第一个键值交换,因此是不稳定排序;例如:2(1),2(2),1对其按由小到大排序,这里2(1)与2(2)表示第一个2和第二个2,选择排序后:1、2(2)、2(1),很明显这两个2的顺序发生变化,则说明选择排序是不稳定排序。
3、选择排序只需一个额外的空间,所以空间复杂度为最佳。
4、此排序法适用于数据量小或有部分数据已经排过序的数组。
范例程序:
/*
[名称]:选择排序法
*/
#include<stdio.h>
#define SIZE 5
void showdata(int *);//声明输出数组程序
void select(int *);//声明选择排序函数
int main()
{
int data[5]={6,4,9,8,3};
printf("原始数据为:");
showdata(data);
select(data);
getchar();
return 0;
}
void showdata(int data[])
{
for(int i=0;i<SIZE;i++)
printf("%d ",data[i]);
printf("\n");
}
void select(int data[])
{
int temp=0;
for(int i=0;i<SIZE-1;i++)
{
for(int j=i+1;j<SIZE;j++)
{
if(data[i]>data[j])
{
temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
printf("第%d次排序结果:",(i+1));
showdata(data);
}
}
输出结果: