这里把所有关于堆的操作写出来。当做标程吧。
#include<stdio.h> #include<stdlib.h> #define ms 1025 typedef struct _heap { int a[ms]; int size; }heap; heap h; static void _shift(heap *h, int i) { int j, t, *a = h ? h->a : 0, n = h ? h->size : 0; if (!h) return; t = a[i]; while ((j = (i<<1)+1) < n) { if (j < n - 1 && a[j] > a[j+1]) ++j; if (a[j] < t) { a[i] = a[j]; i = j; } else break; } a[i] = t; } static void _increase_key(heap *h, int i, int key) { int j, t, *a = h ? h->a : 0, n = h ? h->size : 0; if (!h) return; t = a[i] = key; while ((j = (i>>1)) >= 0 && j != i) { if (a[j] > t) { a[i] = a[j]; i = j; } else break; } a[i] = t; } void build_heap(heap *h) { int i = 0, *a = h ? h->a : 0, n = h ? h->size : 0; if (!h) return; for (i = (n - 2) >> 1; i >= 0; --i) _shift(h, i); } int pop(heap *h) { int m, *a = h ? h->a : 0, n = h ? h->size : 0; if (!h || 0 == n) return -1; m = a[0]; a[0] = a[n-1]; h->size--; _shift(h, 0); return m; } void push(heap *h, int v) { int *a = h ? h->a : 0, n = h ? h->size : 0; if (!h) return; h->size ++; _increase_key(h, h->size - 1, v); } int main(void) { int i = 0, n, v; while (scanf("%d", &n) != EOF) { h.size = 0; for (i = 0; i < n; ++i) { scanf("%d", &v); push(&h, v); } build_heap(&h); while (h.size > 1) printf("%d ", pop(&h)); printf("%d\n", pop(&h)); } return 0; }
1、2、3、
4、
b 排序之后再进行计算,或者用最小堆,每次取最小的数来求和。
c 建立一个100万个数的堆
d 实际上是归并排序,在算法导论中也有提及,就是把这k个要归并的,建立成为k元堆,每次取出最小的,并把这个最小的所在链的下一个加入堆中。
5、没看明白
6、7、值得研究