2010北邮上机真题——哈夫曼树
- 题目描述:
-
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
- 输入:
-
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
-
输出权值。
输出:
- 样例输入:
-
5 1 2 2 5 9
- 样例输出:
-
37
我的困惑
(1)用的数组建立哈夫曼树,然后求出wpl,但是九度上总是报出runtime error的错误,太困惑了,求指导啊,为什嘛啊(2)用链表实现的哈夫曼树就可以ac,蛋疼啊!实现代码
顺序表未ac代码
#include <stdio.h> #include <stdlib.h> #define N 2000 #define M 2 * N - 1 #define MAX 1000 struct hfm { int weight; int lchild; int rchild; int parent; }; void initHfmtree(struct hfm *); void createHfmtree(struct hfm*, int, int); void calculateLength(struct hfm*, int); int main() { int n, m, i; struct hfm htree[M]; while(scanf("%d", &n) != EOF) { m = 2 * n - 1; initHfmtree(htree); for(i = 0; i < n; i ++) { scanf("%d", &htree[i].weight); } createHfmtree(htree, n, m); calculateLength(htree, n); } return 0; } void initHfmtree(struct hfm *htree) { int i; for(i = 0; i < M; i ++) { htree[i].weight = 0; htree[i].lchild = htree[i].rchild = htree[i].parent = -1; } } void createHfmtree(struct hfm *htree, int n, int m) { int m1, m2, loc1, loc2, i, k; for(i = n; i < m; i ++) { m1 = m2 = MAX; loc1 = loc2 = -1; for(k = 0; k < i; k ++) { if(htree[k].parent == -1) { if(htree[k].weight < m1) { m2 = m1; loc2 = loc1; m1 = htree[k].weight; loc1 = k; }else if(htree[k].weight < m2) { loc2 = k; m2 = htree[k].weight; } } } htree[loc1].parent = i; htree[loc2].parent = i; htree[i].weight = m1 + m2; htree[i].lchild = loc1; htree[i].rchild = loc2; } } void calculateLength(struct hfm *htree, int n) { int p, i, count, sum; sum = 0; for(i = 0; i < n; i ++) { count = 0; p = htree[i].parent; while(p != -1) { count ++; p = htree[p].parent; } sum += count * htree[i].weight; } printf("%d\n", sum); }
链表ac代码
#include <stdio.h> #include <stdlib.h> #include <string.h> //哈夫曼结点类型定义 struct huffmancode { int power; struct huffmancode *lchild; struct huffmancode *rchild; struct huffmancode *next; }; //栈类型定义 struct stack { struct huffmancode* data[100]; int top; }; //函数声明 void addNode(struct huffmancode*, struct huffmancode *); struct huffmancode* createHuffmanTree(int, int *); void preTraverse(struct huffmancode*); int getWPL(struct huffmancode*, int); void freeHuffmantree(struct huffmancode *); int main() { int n, i, wpl; int weight[1001]; struct huffmancode *root; while(scanf("%d", &n) != EOF) { //接收权值数据 for(i = 0; i < n; i ++) { scanf("%d", weight + i); } //构建哈夫曼树 root = createHuffmanTree(n, weight); //获取wpl wpl = getWPL(root, 0); printf("%d\n", wpl); //清理哈夫曼树 freeHuffmantree(root); } return 0; } /** * Description:构建哈夫曼树 */ struct huffmancode* createHuffmanTree(int n, int *weight) { int i; struct huffmancode *head, *pl, *pr, *proot; head = (struct huffmancode *)malloc(sizeof(struct huffmancode)); head->next = NULL; //初始化森林 for(i = 0; i < n; i ++) { struct huffmancode *pnode = (struct huffmancode *)malloc(sizeof(struct huffmancode)); pnode->power = *(weight + i); pnode->lchild = pnode->rchild = pnode->next = NULL; addNode(head, pnode); } //构造哈夫曼树 while(head->next->next) { //只有一个节点的情况 if(!head->next->next) { break; } //从单链表中取出节点最小的两个点 pl = head->next; pr = pl->next; //删除pl、pr结点,加入到哈夫曼树中 head->next = pr->next; proot = (struct huffmancode *)malloc(sizeof(struct huffmancode)); proot->power = pl->power + pr->power; proot->lchild = pl; proot->rchild = pr; addNode(head, proot); } return head->next; } /** * Description:添加节点 */ void addNode(struct huffmancode *head, struct huffmancode *pnode) { struct huffmancode *t = head; //找到第一个权值大于给定结点的结点,t指定该结点的前一结点 while(t->next && t->next->power < pnode->power) { t = t->next; } pnode->next = t->next; t->next = pnode; } /** * Description:前序遍历 */ void preTraverse(struct huffmancode *root) { struct huffmancode *head = root; struct stack *s = (struct stack *)malloc(sizeof(struct stack)); s->top = 0; while(head || s->top > 0) { if(head) { printf("%d ", head->power); s->data[s->top ++] = head; head = head->lchild; }else { head = s->data[-- s->top]; head = head->rchild; } } } /** * Description:获取哈夫曼树的带权路径长度 */ int getWPL(struct huffmancode *root, int level) { if(!root) { return 0; } if(!root->lchild && !root->rchild) { return root->power * level; } return getWPL(root->lchild, level + 1) + getWPL(root->rchild, level + 1); } /** * Description:清理哈夫曼树 */ void freeHuffmantree(struct huffmancode *root) { if(!root) { return; } freeHuffmantree(root->lchild); freeHuffmantree(root->rchild); free(root); }
后记
各位,留言指导我一下吧,真心是求指导啊,不知道哪里就数组越界了!!