#include <stdio.h> #include <stdlib.h> /*堆以数组为组织方式,下标从0开始*/ #define INIT_ARRAY_SIZE 50 /*函数声明部分*/ void build_heap(int par_array[], int length); void max_heap_adjust(int par_array[], int index); void heap_sort(int par_array[], int length); void max_heap_insert(int **par_array, int item_value); void heap_delete(int par_array[], int item_value); int left(int index); int right(int index); /*全局变量*/ int heap_size;/*堆大小*/ int heap_cap_size;/*堆容量*/ /*函数定义部分*/ /*返回以index为根的完全二叉树的左子树的索引,整个二叉树索引以0为开始*/ int left(int index) { return ((index<<1) + 1); } /*返回以index为根的完全二叉树的右子树的索引,整个二叉树索引以0为开始*/ int right(int index) { return ((index<<1) + 2); } /*交换两变量的值*/ void swap(int * a, int * b) { int temp = *a; *a = *b; *b = temp; return ; } /* * 堆调整 * 判断根结点和左右结点的大小,选择最大一个 * 如果根大于两个孩子结点,则直接退出; * 否则进行交换,并递归调用调整相应的孩子结点下面的子堆 */ void max_heap_adjust(int par_array[], int index) { int left_index; int right_index; int largest = index; left_index = left(index); right_index = right(index); if(left_index <= (heap_size-1) && par_array[left_index] > par_array[largest]) largest = left_index; if(right_index <= (heap_size-1) && par_array[right_index] > par_array[largest]) largest = right_index; if(index == largest) return ; else { swap(&par_array[index], &par_array[largest]); max_heap_adjust(par_array, largest); } } /* * 建堆过程 * 我们只需依次将以序号为[n/2], [n/2]-1,…,1的结点作为根的子树都调整为堆即可。 */ void build_heap(int par_array[], int length) { heap_size = length; for(int i = ((length-1)>>1); i >= 0; --i) { max_heap_adjust(par_array, i); } } /* * 堆排序 * 首先a[0]和a[n-1]交换,这样在余下的序列a[0-(n-1)]中,只除了根a[0]外,其他各个结点仍然维持堆结构, * 我们再以a[0]开始,做一次堆调整,序列a[0-(n-1)]便调整好了;接下来继续重复上面步骤n-1次,整个序列变得有序. */ void heap_sort(int par_array[], int length) { int i = 0; int temp_heap_size = heap_size;/*保存堆大小*/ for(i = length-1; i >= 1; --i) { swap(&par_array[0], &par_array[i]); heap_size--; max_heap_adjust(par_array, 0); } heap_size = temp_heap_size;/*还原堆大小*/ return ; } /* * 堆的插入和删除算法 * 堆的插入算法:直接把结点插入到堆末尾,然后从下往上冒泡到合适的位置; * 堆的删除算法:把最后一个结点插入删除结点的位置,然后进行一次调整. */ void max_heap_insert(int **par_array, int item_value) { int index = 0; int father_index = 0; /*如果超过动态数组大小,则对其内容进行扩充*/ if(heap_size+1 > heap_cap_size) { *par_array = (int *)realloc(*par_array, 2*INIT_ARRAY_SIZE*sizeof(int)); } (*par_array)[heap_size] = item_value; index = item_value; heap_size++; while(index) { father_index = (index-1)/2; if((*par_array)[index] > (*par_array)[father_index]) swap(&((*par_array)[index]), &((*par_array)[father_index])); index = father_index; } } void heap_delete(int par_array[], int item_value) { int i = 0; for(i = 0; i < heap_size; i++) { if(par_array[i] == item_value) break; } par_array[i] = par_array[heap_size-1]; heap_size--; max_heap_adjust(par_array, i); } int main(void) { int i = 0; int del_value = 0; int i_o_array[INIT_ARRAY_SIZE] = {45,68,20,39,88,97,46,59};/*初始数组*/ int * i_array = NULL;/*实际存储堆用动态数组*/ int array_size/* = sizeof(i_array)/sizeof(int)*/; i_array = (int *)malloc(INIT_ARRAY_SIZE * sizeof(int)); array_size = 8; heap_cap_size = INIT_ARRAY_SIZE; /*初始化动态数组*/ for(i = 0; i < array_size; ++i) i_array[i] = i_o_array[i]; printf("Original array:/n"); for(i = 0; i < array_size; ++i) printf("%d/t", i_array[i]); printf("/n"); build_heap(i_array, array_size); printf("Heap:/n"); for(i = 0; i < array_size; ++i) printf("%d/t", i_array[i]); printf("/n"); heap_sort(i_array, array_size); printf("After heap sort:/n"); for(i = 0; i < array_size; ++i) printf("%d/t", i_array[i]); printf("/n"); del_value = 45; heap_delete(i_array, del_value); array_size--; build_heap(i_array, array_size); printf("Delete %d:/n", del_value); for(i = 0; i < array_size; ++i) printf("%d/t", i_array[i]); printf("/n"); build_heap(i_array, array_size); max_heap_insert((int **)&i_array, 45); array_size++; printf("Insert %d:/n", del_value); for(i = 0; i < array_size; ++i) printf("%d/t", i_array[i]); printf("/n"); heap_sort(i_array, array_size); printf("After heap sort:/n"); for(i = 0; i < array_size; ++i) printf("%d/t", i_array[i]); printf("/n"); system("pause"); return 0; } /* 结果输出: Original array: 45 68 20 39 88 97 46 59 Heap: 97 88 46 59 68 20 45 39 After heap sort: 20 39 45 46 59 68 88 97 Delete 45: 97 59 88 46 39 68 20 Insert 45: 97 59 88 46 39 68 20 45 After heap sort: 20 39 45 46 59 68 88 97 请按任意键继续. . . */