二叉堆是一个数组,它可以被看成一个近似的完全二叉树。树上的每个节点对应对应数组中的一个元素。堆结构上的一些基本操作的运行时间至多与树的高度成正比,即时间复杂度O(lgn)。
维护堆的性质、建堆、堆排序的代码如下:
/*堆排序
* 二叉堆是一个数组,它可以被看成一个近似的完全二叉树
* */
/*定义数组类型*/
typedef int arr_type;
/*定义堆结构体*/
typedef struct heap_struct
{
arr_type *array;
int arr_length;
int heap_size;
} heap;
/*定义宏,分别计算父节点、左孩子、右孩子的下标*/
#define PARENT(i) (i / 2)
#define LEFT(i) (2 * i)
#define RIGHT(i) (2 * i + 1)
/*维护最大堆的性质
* @heap_arg 指向一个堆结构的指针
* @i 根结点下标*/
void max_heapify(heap *heap_arg, int i)
{
int l = LEFT(i);
int r = RIGHT(i);
int largest = i; /*用来记录比根结点大的元素的下标*/
arr_type ele_l = (heap_arg->array)[l]; /*左孩子*/
arr_type ele_r = (heap_arg->array)[r]; /*右孩子*/
arr_type ele_i = (heap_arg->array)[i]; /*根结点*/
arr_type tmp;
if (l <= heap_arg->heap_size && ele_l > ele_i)
{
largest = l;
}
if (r <= heap_arg->heap_size && ele_r > (heap_arg->array)[largest])
{
largest = r;
}
if (largest != i)
{
tmp = (heap_arg->array)[largest];
(heap_arg->array)[largest] = (heap_arg->array)[i];
(heap_arg->array)[i] = tmp;
max_heapify(heap_arg, largest);
}
}
/*建堆
* 注:子数组A(floor(n/2) + 1 ... n)中的元素都是树的叶节点
* @heap_arg 指向堆结构的指针*/
void build_max_heap(heap *heap_arg)
{
heap_arg->heap_size = heap_arg->arr_length;
int i;
for (i = heap_arg->arr_length / 2; i > 0; i--)
{
max_heapify(heap_arg, i);
}
}
/*堆排序算法
* @heap_arg 待排序的堆
*/
void max_heap_sort(heap *heap_arg)
{
heap_arg->heap_size = heap_arg->arr_length;
arr_type tmp;
build_max_heap(heap_arg); /*构建最大堆*/
int i;
for (i = heap_arg->arr_length; i > 1; i--)
{
tmp = (heap_arg->array)[i];
(heap_arg->array)[i] = (heap_arg->array)[1];
(heap_arg->array)[1] = tmp;
heap_arg->heap_size = heap_arg->heap_size - 1;
max_heapify(heap_arg, 1);
}
}
测试如下:
/*测试堆排序*/
#include <stdio.h>
#include <stdlib.h>
#include "heap_sort.h"
int main(void)
{
arr_type arr_a[13] = {0, 15, 13, 9, 5, 12, 8, 7, 4, 0, 6, 2, 1};
heap *heap_a = (heap *) malloc(sizeof(heap));
heap_a->array = arr_a;
heap_a->arr_length = 12;
heap_a->heap_size = heap_a->arr_length;
printf("The array is ");
for (int i = 1; i < 13; i++)
{
printf("%d ", arr_a[i]);
}
printf("\n");
build_max_heap(heap_a);
printf("The max heap is ");
for (int i = 1; i < 13; i++)
{
printf("%d ", arr_a[i]);
}
printf("\n");
printf("Test max_heapify(): \n");
for (int i = 12; i > 1; i--)
{
int tmp = (heap_a->array)[i];
(heap_a->array)[i] = (heap_a->array)[1];
(heap_a->array)[1] = tmp;
for (int j = 1; j < 13; j++)
{
printf("%d ", arr_a[j]);
}
heap_a->heap_size -= 1;
max_heapify(heap_a, 1);
printf("\n");
}
printf("Test max_heap_sort(): \n");
max_heap_sort(heap_a);
for (int i = 1; i < 13; i++)
{
printf("%d ", arr_a[i]);
}
printf("\n");
free(heap_a);
return 1;
}