哈夫曼树
来源:互联网 发布:招商银行外汇交易软件 编辑:程序博客网 时间:2024/05/24 06:25
点击打开链接
•哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
•输入:
•输入有多组数据。
•每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
•输出:
•输出权值。
•样例输入:
•5
•1 2 2 5 9
•样例输出:
•37
算法一:
nclude<iostream> #include<stack> using namespace std; int result[1001]; //哈夫曼树的权值就是除了所有叶子
//的节点的权值的和 int main(){ int n,i,sum,num; while(scanf("%d",&n)!=EOF){ memset(result,0,n); for(i=0;i<n;i++) scanf("%d",&result[i]); //进行排序,从小到大 sort(result,result+n); i=1; sum=0; while(i<n){ //每次都要进行重新排序,因为生成了新的节点 sort(result+i-1,result+n); //计算父亲 num = result[i-1]+result[i]; sum+=num; //将新的节点赋值 result[i]=num; i++; } printf("%d\n",sum); } return 0; }
#include <string.h> #include <algorithm> #include<iostream> #include<stack> #define maxvalue 0x7fffffff//这个是int的最大值 using namespace std; //创建节点的结构体 struct huffman{ int weight; int parent,lchild,rchild; }list[5000]; int main() { int n,m; int i,j; int ans; int x1,x2;//用来存放树生成过程中的最小和次小的角标 int m1,m2;//用来存放树生成过程中的最小和次小的值 while(scanf("%d",&n)!=EOF) { m=2*n-1; //生成2n-1个节点 for(i=0;i<m;i++) list[i].parent=list[i].lchild=list[i].rchild=-1; for(i=0;i<n;i++) scanf("%d",&list[i].weight); ans=0; for(i=0;i<n-1;i++){ x1=x2=0; m1=m2=maxvalue; for(j=0;j<n+i;j++){ //用来判断新的节点是否小于最小且没有双亲 //如果小于最小的话就把当前的数和角标给x1和m1 //并且在x1和m1中存入当前最小的角标和值 if(list[j].weight<m1&&list[j].parent==-1){ x2=x1; m2=m1; x1=j; m1=list[j].weight; } //用来判断是不是小于次小,如果小于的话就替换次小 else if(list[j].weight<m2&&list[j].parent==-1){ x2=j; m2=list[j].weight; } } list[x1].parent=n+i; list[x2].parent=n+i; list[n+i].lchild=x1; list[n+i].rchild=x2; list[n+i].weight=list[x1].weight+list[x2].weight; ans+=list[n+i].weight; } printf("%d\n",ans); } return 0; }算法三:这个是针对于此类型的题比较完整的算法,可我现在还不太理解,对指针还不熟悉,可能以后回过来看会理解。
/*示例 ****哈夫曼编码****请输入结点个数:8输入这8个元素的权值(均为整形):1:272:43:874:215:26:217:18:25*/#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct{ unsigned int weight; //用来存储各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组,存储哈夫曼树///选择两个parent为0,且weight最小的结点s1和s2 void Select(HuffmanTree *ht,int n,int *s1,int *s2){ int i,min; for(i=1; i<=n; i++) { if((*ht)[i].parent==0) { min=i; break; } } for(i=1; i<=n; i++) { if((*ht)[i].parent==0){ if((*ht)[i].weight<(*ht)[min].weight) min=i;} } *s1=min; for(i=1; i<=n; i++) { if((*ht)[i].parent==0 && i!=(*s1)){ min=i; break;} } for(i=1; i<=n; i++) { if((*ht)[i].parent==0 && i!=(*s1)){ if((*ht)[i].weight<(*ht)[min].weight) min=i;} } *s2=min;}///构造哈夫曼树ht,w存放已知n个权值 void CrtHuffmanTree(HuffmanTree *ht,int *w,int n){ int m,i,s1,s2; m=2*n-1; //总共的结点数 *ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(i=1; i<=n; i++) //1-n号存放叶子结点,初始化 { (*ht)[i].weight=w[i]; (*ht)[i].LChild=0; (*ht)[i].parent=0; (*ht)[i].RChild=0; } for(i=n+1; i<=m; i++) //非叶子结点的初始化 { (*ht)[i].weight=0; (*ht)[i].LChild=0; (*ht)[i].parent=0; (*ht)[i].RChild=0; } printf("\n?哈夫曼树为: \n"); for(i=n+1; i<=m; i++) //创建非叶子结点,建哈夫曼树 { /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2*/ Select(ht,i-1,&s1,&s2); (*ht)[s1].parent=i; (*ht)[s2].parent=i; (*ht)[i].LChild=s1; (*ht)[i].RChild=s2; (*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight; printf("%d (%d, %d)\n",(*ht)[i].weight,(*ht)[s1].weight,(*ht)[s2].weight); } printf("\n");} //从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n){ char *cd; //定义的存放编码的空间 int a[100]; int i,start,p,w=0; unsigned int c; hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); //分配n个编码的头指针 cd=(char *)malloc(n*sizeof(char)); //分配求当前编码的工作空间 cd[n-1]='\0'; //从右向左逐位存放编码,首先存放编码结束符 for(i=1; i<=n; i++) //求n个叶子结点对应的哈夫曼编码 { a[i]=0; start=n-1; //起始指针位置在最右边 for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) //从叶子到根结点求编码 { if( (*ht)[p].LChild==c){cd[--start]='1'; //左分支标1a[i]++;} else {cd[--start]='0'; //右分支标0a[i]++;} } hc[i]=(char *)malloc((n-start)*sizeof(char)); //为第i个编码分配空间 strcpy(hc[i],&cd[start]); //将cd复制编码到hc } free(cd); for(i=1; i<=n; i++) printf(" 权值为%d的哈夫曼编码为:%s\n",(*ht)[i].weight,hc[i]); for(i=1; i<=n; i++) w+=(*ht)[i].weight*a[i]; printf(" 带权路径为:%d\n",w);}int main(){ HuffmanTree HT; HuffmanCode HC; int *w,i,n,wei; printf("**哈夫曼编码**\n" ); printf("请输入结点个数:" ); scanf("%d",&n); w=(int *)malloc((n+1)*sizeof(int)); printf("\n输入这%d个元素的权值:\n",n); for(i=1; i<=n; i++) { printf("%d: ",i); fflush(stdin);//清空输入缓冲区; scanf("%d",&wei); w[i]=wei; } CrtHuffmanTree(&HT,w,n); CrtHuffmanCode(&HT,&HC,n); system("pause"); return 0;}
阅读全文
0 0
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 哈夫曼树
- 写个自己看的博客_UGUI_DragDrop官网例子
- MySQL慢SQL优化-如何分析性能瓶颈
- 抽象类 接口 区别
- mac+phpstorm+xdebug 最精炼安装方法
- fio使用指南(最全的参数说明)
- 哈夫曼树
- MathUtil 中的生成随机序列方法(仿C中的扑克牌算法)
- UVa 11489
- Java设计模式之工厂方法模式
- UVA 1593
- ORACLE中 SEQUENCE自动增长 用法
- 在Pycharm中自动添加时间日期作者等信息
- 装载机稳定模块讲解
- iOS学习笔记-087.彩票02——自定义tabBar