xdoj-哈夫曼树

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);
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值