选择排序的基本思想: 每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

void SelectSort(int* arr, int n)
{
int begin = 0, end = n - 1;
while (begin < end)
{
int mini = begin;
int maxi = begin;
for (int i = begin + 1; i <= end; i++)
{
if (arr[i] < arr[mini])
{
mini = i;
}
if (arr[i] > arr[maxi])
{
maxi = i;
}
}
if (maxi == begin)
{
maxi = mini;
}
Swap(&arr[begin], &arr[mini]);
Swap(&arr[end], &arr[maxi]);
begin++;
end--;
}
}直接选择排序的特性总结:
堆排序的算法思想基于堆这种数据结构(完全二叉树),核心步骤如下:
通过堆的特性,每次能高效地选出剩余元素中的最大值(或最小值),最终实现整个数组的有序排列。堆排序的时间复杂度为O(n*logn),空间复杂度为O(1)。
大家要是想进一步详细了解可以参考:小年糕是糕手博客 -- 顺序结构二叉树详解
void Swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
//向上调整算法
void AdjustUp(int* arr, int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
//建大堆: >
//建小堆: <
if (arr[child] > arr[parent])
{
Swap(&arr[child], &arr[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
//不用调整符合情况
break;
}
}
}
//向下调整算法
//n是堆里面的结点个数,如果越界了就不需要调整了
void AdjustDown(int* arr, int parent, int n)
{
int child = parent * 2 + 1;
while (child < n)
{
//建大堆: <
//建小堆: >
if (child + 1 < n && arr[child] < arr[child + 1])
{
child++;
}
//孩子和父亲比较
//建大堆: >
//建小堆: <
if (arr[child] > arr[parent])
{
Swap(&arr[child], &arr[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//堆排序
void HeapSort(int* arr, int n)
{
//向下调整算法 -- 建堆n
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(arr, i, n);
}
////向上调整算法 -- 建堆n*logn
//for (int i = 0; i < n; i++)
//{
// AdjustUp(arr, i);
//}
//n*logn
int end = n - 1;
while (end > 0)
{
Swap(&arr[0], &arr[end]);
AdjustDown(arr, 0, end);
end--;
}
}堆排序的特性总结如下: