堆排序
步骤
1、将数组按照完全二叉树的方法进行构建二叉树
2、从层次遍历的最后一个非叶子结点开始进行调整(根结点小于某个叶子结点,则将最大的叶子结点与根结点进行交换),依次往前
3、调整为大顶堆或者小顶堆后,将堆顶元素和堆中最后一个元素进行交换,最后一个元素脱离堆结构,堆的规模减1,将堆中剩余的元素调整成大顶堆或小顶堆
4、重复步骤3,直到只剩最后一个元素在堆结构中。
代码
#include <stdio.h>
#define MAXITEM 100
void Heapify(int R[MAXITEM], int v, int n)
{
int i, j;
i = v;
j = 2 * i; //编号为v的左子树
R[0] = R[i]; //临时存储
while (j <= n) //判断j是否在数组中
{
//找到左右子树数值较大的下标
if ((j < n) && (R[j] < R[j + 1])) //j<n--确保存在右子树
{
j++;
}
//交换结点
if (R[0] < R[j])
{
R[i] = R[j];
i = j;
j = 2 * i;
}
else
{
j = n + 1;
}
R[i] = R[0];
}
}
//堆排序,R为待排序数组,n为数组大小
void HeapSort(int R[MAXITEM], int n)
{
int i;
//构建初试大顶堆
for (i = n / 2; i >= 1; i--) //从最后一个非叶子结点(n/2)开始调整
{
Heapify(R, i, n);
}
//调整大顶堆,将堆顶元素和堆中最后一个元素进行交换,最后一个元素脱离堆结构,堆的规模减1,将堆中剩余的元素调整成大顶堆
for (i = n; i > 1; i--) //最后一个元素不需要排序了
{
R[0] = R[i];
R[i] = R[1];
R[1] = R[0];
Heapify(R, 1, i - 1);
}
}
int main()
{
int R[] = { 0, 7, 10, 13, 15, 4, 20, 19, 8 };
int n = 8; //堆中的元素数
HeapSort(R, n);
for (int k = 1; k <= n; k++)
{
printf("%d ", R[k]);
}
return 0;
}
时间复杂度:O(nlogn)
空间复杂度:O(1)