编程珠玑第14章

这里把所有关于堆的操作写出来。当做标程吧。

#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、值得研究



你可能感兴趣的:(编程珠玑第14章)