首先来看看选择排序法的定义
核心思想就是先在所有数据中选出一个最大或者最小的数放在第一位,然后再剩下的数据继续选最大或者最小的数放在第二位,依次进行下去直到结束。
下来直接看C代码的实现
#define EXCHANGE(num1, num2) { num1 = num1 ^ num2; num2 = num1 ^ num2; num1 = num1 ^ num2;}
void selectSort( int num[], int count )
{
for( int i = 0; i < count; i++ )
{
int min = i;
for( int j = i; j < count; j++ )
{
if( num[j] < num[min] )
{
min = j;
}
}
if( i != min )
{
EXCHANGE( num[i], num[min] ); //可以看出,最多交换count - 1次
}
}
}
下来单步分析一下排序过程
这是要排序的原始数据,首先将第0个元素当做最小的数,然后再剩下的数据中查找比它更小数。由于0已经是本数组中最小的数,所以当i=0时,没有找到更小的数,于是i++,这时候 i 为1,指向了第二个数字8,此时在后面的数字中寻找最小的数,8后面数字中最小的数是1,由于1<8,所以此时要交换1和8的位置。交换位置后新数组为:
然后变量i继续加1,这时候i=2,指向了数组中第三个数,此时第三个数还是8,然后在剩余的数字中寻找最小的数,此时最小的数是2,那么8就和2交换位置,交换位置后新的数组为:
变量i继续加1,此时i=3,最小值指向了5,在剩余数字中寻找最小的数,此时3是剩余数字中最小的数,交换3和5的位置,交换后数组变为:
下来i的值加1,最小值指向了4,然后在剩余数字里面找比4小的数字,没有找到比4小的数字,于是i继续加1,指向了5,后面还没有比5小的数字,于是i继续加1,最小值指向了7,在后面找到了比7小的数字6,于是交换6和7的位置。
变量i的值继续加1,此时最小的值指向了9,剩余数字中最小的数为7,将7和9交换位置。
下来i的值继续加1,最小值指向了8,剩余一个数字9比8大,i继续加1,指向最后一个数字,此时说明数组中所有的数已经排序完成,退出循环。
可以看出用选择排序法对数组排序时,速度非常快。在用冒泡排序法对这10个数字排序时总共需要44趟比较才能完成,而用选择排序法时只需要10次比较就能排序完成。
下来测试一下用选择排序法最坏情况下需要多次
最坏情况下需要10次,在测试下最好情况下需要多次
最好情况也需要10次。
下来随机生成一个包含10000个数字的数组,测试下执行时间。
可以看到10000个数据时需要比较10000次,需要的时间为219ms,比较次数和时间比冒泡排序法快了很多。
用一张动图演示一下选择排序法的排序的过程。
完整的测试代码贴在下面
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define showInfo 0
#define COUNT 10000
#define EXCHANGE(num1, num2) { num1 = num1 ^ num2; num2 = num1 ^ num2; num1 = num1 ^ num2;}
//int num[10]= {9,8,7,6,5,4,3,2,1,0};
//int num[10] = {0,1,2,3,4,5,6,7,8,9};
int num[COUNT] = {0,8,1,5,4,3,7,9,2,6};
//打印数组元素
void printf_nums( int num[], int count )
{
int i = 0;
for( i = 0; i < count; i++ )
{
printf( "%d ", num[i] );
}
printf( "\r\n" );
}
//生成随机数组
void randNum( int* num, int count )
{
int i = 0;
while( i < count )
{
num[i++] = rand() % 99;
}
}
void selectSort( int num[], int count )
{
int cnt = 0,i=0,j=0;
#if showInfo
printf( "原始数组:" );
printf_nums( num, count );
#endif
for( i = 0; i < count; i++ )
{
int min = i;
for( j = i; j < count; j++ )
{
if( num[j] < num[min] )
{
min = j;
}
}
if( i != min )
{
EXCHANGE( num[i], num[min] ); //可以看出,最多交换count - 1次
}
cnt++;
#if showInfo
printf( "第%3d趟 : ", cnt );
printf_nums( num, count );
#endif
}
printf("共执行了%d次!\r\n",cnt);
}
int main()
{
clock_t start,stop;
start = clock();
puts("selectSort test");
randNum(num,COUNT);
selectSort(num,COUNT);
stop = clock();
printf("执行时间为%d ms\r\n",stop-start);
system("pause");
return 0;
}