哈夫曼树
前言
学习贪心算法的时候复习了一下哈夫曼树的构造,这里记录一下,参考链接:http://blog.csdn.net/zinss26914/article/details/8461596
主要是记录一道九度的哈夫曼树的题目
题目
题目描述: 哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。 输入: 输入有多组数据。 每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。 输出: 输出权值。 样例输入: 5 1 2 2 5 9 样例输出: 37
ac代码
链表构建哈夫曼树(插入排序)
#include <stdio.h>
#include <stdlib.h>
#define max 1001
struct htree
{
int weight;
struct htree *lchild;
struct htree *rchild;
struct htree *next;
};
void addNode(struct htree *, struct htree *);
struct htree* createHfmtree(int *, int);
int getWpl(struct htree *, int);
int main()
{
int w[max];
int i, n, wpl;
struct htree *ht;
while(scanf("%d", &n) != EOF)
{
for(i = 0; i < n; i ++)
{
scanf("%d", &w[i]);
}
ht = createHfmtree(w, n);
wpl = getWpl(ht, 0);
printf("%d\n", wpl);
}
return 0;
}
struct htree* createHfmtree(int *w, int n)
{
int i;
struct htree *head, *pl, *pr, *proot;
head = (struct htree *)malloc(sizeof(struct htree));
head->next = NULL;
for(i = 0; i < n; i ++)
{
struct htree *pnode = malloc(sizeof(struct htree));
pnode->weight = *(w + i);
pnode->lchild = pnode->rchild = pnode->next = NULL;
addNode(head, pnode);
}
while(head->next)
{
if(head->next->next == NULL)
break;
pl = head->next;
pr = pl->next;
head->next = pr->next;
proot = (struct htree *)malloc(sizeof(struct htree));
proot->weight = pl->weight + pr->weight;
proot->lchild = pl;
proot->rchild = pr;
addNode(head, proot);
}
return head->next;
}
void addNode(struct htree *head, struct htree *pnode)
{
struct htree *t = head;
while(t->next && t->next->weight < pnode->weight)
t = t->next;
pnode->next = t->next;
t->next = pnode;
}
int getWpl(struct htree *ht, int level)
{
if(ht == NULL)
return 0;
if(!ht->lchild && !ht->rchild)
{
return ht->weight * level;
}
return getWpl(ht->lchild, level + 1) + getWpl(ht->rchild, level + 1);
}
最小堆+贪心(堆排序)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1001
void minHeapIfy(int *A, int i, int n);
void buildMinHeap(int *A, int n);
int heapExtractMin(int *A, int n);
void minHeapInsert(int *A, int i, int key);
int main()
{
int i, j, n, huff[MAX], power, lchild, rchild, parent;
while(scanf("%d", &n) != EOF)
{
//接收参数输入
for(i = 1; i <= n; i ++)
scanf("%d", &huff[i]);
//构建一个最小堆
buildMinHeap(huff, n);
//获取wpl
for(i = 1, j = n, power = 0; i < n; i ++)
{
lchild = heapExtractMin(huff, j);
j -= 1;
rchild = heapExtractMin(huff, j);
parent = lchild + rchild;
power += parent;
minHeapInsert(huff, j, parent);
}
printf("%d\n", power);
}
return 0;
}
/**
* Description:构建最小堆
*/
void buildMinHeap(int *A, int n)
{
int i;
for(i = n / 2; i >= 1; i --)
{
minHeapIfy(A, i, n);
}
}
/**
* Description:调整以i为根的最小堆
*/
void minHeapIfy(int *A, int i, int n)
{
int l, r, min, loc, temp;
for(min = i; min <= n;)
{
l = min * 2;
r = min * 2 + 1;
loc = min;
if(l <= n && A[l] < A[min])
min = l;
if(r <= n && A[r] < A[min])
min = r;
if(min != loc)
{
temp = A[min];
A[min] = A[loc];
A[loc] = temp;
}else
{
break;
}
}
}
int heapExtractMin(int *A, int n)
{
int min = A[1];
A[1] = A[n];
minHeapIfy(A, 1, n);
return min;
}
/**
* Description:
* (1)将元素插入到最小优先队列
* (2)因为每次i == length(A),都是在对尾插入,因此只考虑i的parent,不考虑i的children
*/
void minHeapInsert(int *A, int i, int key)
{
int parent, change;
for(A[i] = key, parent = i / 2; parent >= 1 && A[parent] > A[i];)
{
change = A[parent];
A[parent] = A[i];
A[i] = change;
i = parent;
parent = i / 2;
}
}后记
参考我之前写的那篇博客效果更佳!

浙公网安备 33010602011771号