选择排序算法就是每一趟从待排序的记录中选出关键字最小(最大)的记录,顺序放在已排好序的子文件的最后(最前),直到全部记录排序完毕。常见的选择排序有直接选择排序(Selection Sort),堆排序(Heap Sort),平滑排序(Smooth Sort),笛卡尔树排序(Cartesian Sort),锦标赛排序(Tournament Sort),循环排序(Cycle)。下面介绍前两种:
(一)直接选择排序
最差时间复杂度:O(n^2)
最优时间复杂度:O(n^2)
平均时间复杂度:O(n^2)
稳定性:不稳定
直接选择排序(Selection Sort),这是一种简单直观的排序算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的其起始位置,然后再从剩余未排序的序列元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素排序完毕。
算法示意图:
实现代码:
void SelectSort(int *a, int len)
{
for (int i=0; i
(二)堆排序
最差时间复杂度:O(nlogn)堆排序(Heap Sort),是利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。
通常堆是通过一维数组来实现的,在起始数组为0的情形中,对于节点i:3.堆排序(Heap Sort):首先创建最大堆,然后依次将堆的根节点与末节点交换、剔除末节点、对根节点进行最大堆调整,直到堆中的节点数为1,排序结束。
算法示意图:
实现代码:
// 最大堆调整
void MaxHeapify(int *a, int i, int heapSize)
{
int l = (i+1)*2-1;
int r = (i+1)*2;
int largest;
if (l<=heapSize && a[l]>a[i])
largest = l;
else
largest = i;
if (r<=heapSize && a[r]>a[largest])
largest = r;
if (largest!=i)
{
swap(a[i], a[largest]);
MaxHeapify(a, largest, heapSize);
}
}
// 创建最大堆
void BuildMaxHeap(int *a, int len)
{
for (int i=len/2-1; i>=0; i--)
{
MaxHeapify(a, i, len-1);
}
}
// 堆排序
void HeapSort(int *a, int len)
{
BuildMaxHeap(a, len);
for (int i=len-1; i>0; i--)
{
swap(a[0], a[i]);
MaxHeapify(a, 0, i-1);
}
}