选择排序有两种,一种是选择排序,一种是堆排序。
选择排序就是将最大的数和最小的数选出来放到边界,然后缩小范围再选出次大的和次小的放到边界然后再缩小范围直到数组中只剩下最后一个数,这时排序完成。
代码如下:
void SelectSort(int *a, int size)
{
assert(a);
int left = 0, right = size - 1; //left为左边界,right为右边界
while (left < right)
{
int min, max;
min = max = left;
for (int i = left; i <= right; ++i) //遍历一趟在相对应的范围里选择出最大的数和最小的数
{
if (a[i] > a[max])
max = i;
if (a[i] < a[min])
min = i;
}
swap(a[min], a[left]); //交换
if (left == max) //特殊处理,防止出现死循环
{
max = min;
}
swap(a[right], a[max]);
++left; //缩小边界范围
--right;
}
堆排序是时间复杂度最优的一种排序,之间在写堆的时候有涉及过,堆排序就是利用堆的特性建大堆来进行排序。代码如下:
void AdjustDown(int *a, int root, int size) //向下调整
{
int parent = root;
int child = parent * 2 + 1;
while (child < size)
{
if (child + 1 < size&&a[child + 1] > a[child]) //选出左右孩子中较大的那个
++child;
if (a[child]>a[parent]) //交换
{
swap(a[child], a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int *a, int size) //堆排序
{
assert(a);
//建堆
for (int i = (size - 2) / 2; i >= 0; --i)
{
AdjustDown(a,i,size);
}
int end = size - 1;
while (end > 1) //随着end的减小,堆不断地调整着,把最大的数放到后面
{
AdjustDown(a,0, end);
--end;
}
}