xdoj-哈夫曼树
问题描述
假设用于通信的电文由n个字符组成,字符在电文中出现的频度(权值)为w1,w2,…,wn,试根据该权值序列构造哈夫曼树,并计算该树的带权路径长度。
输入说明
第1行为n的值,第2行为n个整数,表示字符的出现频度。
输出说明
输出所构造哈夫曼树的带权路径长度。
输入样例
8
7 19 2 6 32 3 21 10
输出样例
261
代码样例
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define MAXSIZE 100
typedef struct node{
int weight;
struct node *lchild, *rchild;
struct node *parent;
}Bitree;
typedef struct linkList{
Bitree *data;
struct linkList *next;
}list;
void Insert(Bitree *tree, list *head){//以节点权值构建递增链表
list *p, *s;
int temp=0;
s=NULL;
s=(list*)malloc(sizeof(list));
s->data=tree;
p=head;
while(p->next!=NULL){
if((s->data->weight) < (p->next->data->weight)){
s->next=p->next;
p->next=s;
temp=1;
break;
}
p=p->next;
}
if(temp==0){//末尾插入情况
p->next=s;
s->next=NULL;
}
}
// Insert
void Delt(list *head){
list *p;
p=head;
p->next=p->next->next->next;
}
// Delt
list *init_tree(int n){//将初始化的节点储存在链表中
int temp=0;
int ori_num;
Bitree *tree;
list *r, *s, *head;
head=(list*)malloc(sizeof(list));
r=head;
while(temp<n){
scanf("%d",&ori_num);
tree=NULL;
tree=(Bitree*)malloc(sizeof(Bitree));
tree->weight=ori_num;
tree->lchild=NULL;
tree->rchild=NULL;
tree->parent=NULL;
if(temp==0){
s=(list*)malloc(sizeof(list));
s->data=tree;
r->next=s;
r=s;
r->next=NULL;
temp++;
}
else{
Insert(tree, head);
temp++;
}
}
return head;
}//此时链表是以权值递增的单链表
// init_tree
Bitree *Huffman(list *head){
Bitree *tree;
list *p, *s;
p=head;
s=NULL;
tree=NULL;
if(p->next->next==NULL){
return p->next->data;
}
else{
while(p->next->next!=NULL){
tree=(Bitree*)malloc(sizeof(Bitree));
tree->weight=p->next->data->weight+p->next->next->data->weight;
tree->parent=NULL;
tree->lchild=p->next->data;
p->next->data->parent=tree;
tree->rchild=p->next->next->data;
p->next->next->data->parent=tree;
Delt(head);
Insert(tree, head);
}
return p->next->data;
}
}
// Huffman
int Deep(Bitree *tree){//求叶子节点的深度
if(tree!=NULL){
int deep=0;
Bitree *t;
t=tree;
while(t->parent!=NULL){
t=t->parent;
deep++;
}
return deep;
}
}
// Deep
int sum=0;
void output(Bitree *tree){//计算哈夫曼树的加权路径长度
if(tree!=NULL){
if((tree->lchild==NULL) && (tree->rchild==NULL)){
sum+=tree->weight * Deep(tree);
}
output(tree->lchild);
output(tree->rchild);
}
}
// output
int main(){
int number;
scanf("%d",&number);
list *s;
s=init_tree(number);
Bitree *t;
t=Huffman(s);
output(t);
printf("%d",sum);
}