#include <stdio.h>#include <stdlib.h>#include <string.h>#define PARENT(x) ((x-1)>>1)#define LEFT(x) (((x)<<1)+1)#define RIGHT(x) (((x)<<1)+2)//#define LEFT(x) ((x)<<1)//#define RIGHT(x) (((x)<<1)+1)int count = 0;void max_heapfiy(int *arr, int len, int i);void build_max_heap(int *arr, int len);void heap_sort(int *arr, int len);//返回最大元素int heap_max(int *arr, int len);//返回最大元素,并删除它,之后保持堆的性质int extract_max(int *arr, int len);//向堆中插入一个值为key的元素,返回插入后的长度int insert_key(int *arr, int len, int key);//修改堆中某一元素的值为keyvoid modify_key(int *arr, int len, int key, int i);int main(){ printf("before build heap:\n"); int i = 0; int num = 12;//00000; int *arr = (int*)malloc(num * sizeof(int));// = {0};//3,9,6,7,2,5,8,1,10,4}; srand(time(NULL)); int t = num; for(i = 0; i < num; i++) { arr[i] = rand()%num + 11; printf("%d,", arr[i]); } printf("\n"); build_max_heap(arr, num); printf("after build heap\n"); for(i = 0; i < num; i++) { printf("%d,", arr[i]); } printf("\n"); //insert_key(arr, num-1, arr[num-1]); //heap_sort(arr, num); int key = 13; modify_key(arr, num, key, 4); printf("after motify heap:\n"); for(i = 0; i < num; i++) { printf("%d,", arr[i]); } printf("\n"); printf("extract max queue:\n"); for(i = 0; i < num; i++) { printf("%d,", extract_max(arr, num - i)); } printf("\n"); printf("efficient is %d\n", count); return 0;}/* * 中心思想: 首先我们假设此过程之前以i节点为根的树已具有堆的性质 * 每次我们从 i 与他的两个孩子中找出最大的一个与根进行比较 * 如果恰好i是最大的,那么此过和结束,如果i不是最大的,便将i与最大的一个 * 孩子进行交换,使其成为根,然后再从该孩子入手,递归的执行此过程。 */void max_heapfiy(int *arr, int len, int i){ int l = LEFT(i); int r = RIGHT(i);// printf("i = %d, l = %d, r = %d\n", i, l, r); int max = i;//假设当前元素为最大元素 //只变换下标,找出最大元素 if(l < len && arr[i] < arr[l]) { max = l; } if(r < len && arr[max] < arr[r]) { max = r;//max标注当前最大元素,但不一定是堆的根 } //交换元素本身 //有个先决假想条件:除了本次max_heapfiy外,其他层的堆都假设是建好的。 //如果i不是当前最大的,则将i变为当前最大的,然后 if(max != i) { int tmp = arr[i]; arr[i] = arr[max]; arr[max] = tmp;//交换后max标注下一次建堆的选择元素 max_heapfiy(arr, len, max); } count++; return ;}/* * 中心思想,由于n元素的堆的叶子结点的下标为: n/2+1 到 n * 所以我们从最后一个非叶子结点 n/2 往上建堆即可(此处以下标为0进行说明) */void build_max_heap(int *arr, int len){ int i = len / 2; for(; i >= 0; i--) { max_heapfiy(arr,len, i); } return ;}void heap_sort(int *arr, int len){ int size = len; build_max_heap(arr, len); while(--size >= 1) { int max = arr[0]; arr[0] = arr[size]; arr[size] = max; max_heapfiy(arr, size, 0); }}int heap_max(int *arr, int len){ if(len <= 0) { return 1<<32; } return arr[0];}int extract_max(int *arr, int len){ if(len <= 0) { printf("under overflow!\n"); exit(0); } int max = arr[0]; arr[0] = arr[len-1]; max_heapfiy(arr, len-1, 0); return max;}int insert_key(int *arr, int len, int key){ if(len < 0) return -1; int i = len; arr[i] = key; while(i > 0 && arr[PARENT(i)] < arr[i]) { int tmp = arr[PARENT(i)]; arr[PARENT(i)] = arr[i]; arr[i] = tmp; i = PARENT(i); } return len+1;}//修改堆中某一元素的值为keyvoid modify_key(int *arr, int len, int key, int i){ if(len <= 0) return; //modify to key //arr[i], key; //rebuild the heap if(arr[i] < key) { arr[i] = key; while(i > 0 && arr[PARENT(i)] < arr[i]) { int tmp = arr[PARENT(i)]; arr[PARENT(i)] = arr[i]; arr[i] = tmp; i = PARENT(i); } } else { arr[i] = key; max_heapfiy(arr, len, i); }}