堆排序
二叉堆是一个数组,它可以被看成一个近似的完全二叉树。树上的每个节点对应对应数组中的一个元素。堆结构上的一些基本操作的运行时间至多与树的高度成正比,即时间复杂度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; }