以升序为例,假设排序5 7 3 2 0 8 4这组数据
void SelectSort(int arr[],int len)
{
int i = 0;
int k = 0;//保存无序区第一个元素下标,方便比较
//一趟确定一个有序区元素,最后一次不用确定,总共len-1次
for (i = 0; i < len - 1; i++)
{
k = i;
int j = 0;
//确定无序区最小元素下标
for (j = i + 1; j < len; j++)
{
if (arr[j] < arr[k])
{
k = j;
}
}
//如果无序区第一个元素为最小,则没有必要交换
if (i != k)
{
int tmp = arr[k];
arr[k] = arr[i];
arr[i] = tmp;
}
}
}
上边的算法的思想是一次确定一个有序区的值(最小值),那我们为何不一次确定两个值(一个最小值和一个最大值)呢?这样做肯定效率可以快很多。
void SelectSort(int arr[], int len)
{
int left = 0;
int right = len - 1;
while (left < right)
{
int max = left;//记录无序区最大元素下标
int min = left;//记录无序区最小元素下标
int j = 0;
for (j = left + 1; j <= right; j++)
{
//找最大元素下标
if (arr[j] < arr[min])
{
min = j;
}
//找最小元素下标
if (arr[j]>arr[max])
{
max = j;
}
}
//最小值如果是第一个则没有必要交换
if (min != left)
{
int tmp = arr[left];
arr[left] = arr[min];
arr[min] = tmp;
}
//这里很重要,如果最大元素下标是left,前面已经和最小元素交换了,此时最大元素下标应该是min
if (max == left)
{
max = min;
}
//最大值如果是最后一个则没必要交换
if (max != right)
{
int tmp = arr[right];
arr[right] = arr[max];
arr[max] = tmp;
}
left++;
right--;
}
}