假定存在数组 array[0..n-1], 选择排序的核心思想是:
第 i 趟排序是从后面的 n – i + 1(i = 1,2,3,4,. . .,n – 1)个元素中选择一个值最小的元素与该 n – i + 1 个元素的最前门的那个元素交换位置,即与整个序列的第 i 个元素交换位置。如此下去,直到 i = n – 1,排序结束。
也可描述为:
每一趟排序从序列中未排好序的那些元素中选择一个值最小的元素,然后将其与这些未排好序的元素的第一个元素交换位置。
特点:
1. 算法完成需要 n – 1 趟排序,按照算法的描述,n – 1 趟排序之后数组中的前 n – 1 个元素已经处于相应的位置,第 n 个元素也处于相应的位置上。
2. 第 i 趟排序,实际上就是需要将数组中第 i 个元素放置到数组的合适位置,这里需要一个临时变量 j 来遍历序列中未排好序的那些元素,另一临时变量 d 来记录未排好序的那些元素中值最小的元素的下标值,
3. 一趟遍历开始时,令 d = i,假定未排序序列的第一个元素就是最小的元素,遍历完成后,变量 d 所对应的值就是值最小的元素,判断 d 是否是未排序序列的第一个元素,如果是,则不需要交换元素,如果不是,则需要交换array[d] 和 array[i]。
4. 此方法是不稳定排序算法,可对数组{a1 = 49,a2 = 38, a3 = 65, a4 = 49, a5 = 12, a6 = 42} 排序就可以看出,排序完成后 a1 和 a4的相对位置改变了。
5. 此方法移动元素的次数比较少,但是不管序列中元素初始排列状态如何,第 i 趟排序都需要进行 n – i 次元素之间的比较,因此总的比较次数为
1 + 2 + 3 + 4 +5 + . . . + n – 1 = n(n-1)/2, 时间复杂度是 O(n^2).
看代码:
#include <stdlib.h>
#include <stdio.h>
void selectSort(int array[], int n)
{
int i, j, d;
int temp;
for(i = 0; i < n - 1; ++i)
{
d = i; //开始一趟选择排序,假定第i个元素是后面n - i + 1个未排序的元素中最小的元素
for(j = i + 1; j < n; ++j)
if(array[j] < array[d]) //如果发现比当前最小元素还小的元素,则更新记录最小元素的下标d
d = j;
if(d != i) //如果最小元素的下标不是后面n - i + 1的未排序序列的第一个元素,则需要交换第i个元素和后面找到的最小元素的位置
{
temp = array[d];
array[d] = array[i];
array[i] = temp;
}
}
}
int main()
{
int array[] = {3, 1, 15, 11, 89, 5};
int size = sizeof(array)/sizeof(int);
selectSort(array, size);
for(int i = 0; i < size; ++i)
{
printf("%d ", array[i]);
}
printf("\n");
}