怎么给哈夫曼树设置字符以及其频度

作者&投稿:皮狱 (若有异议请与网页底部的电邮联系)
输入一组字符及其出现频率,生成其哈夫曼树,并输出每个字符的哈夫曼编码及中序遍历序列。~

这里有个C写的,VC++6.0可以编译
《基于哈夫曼(haffuman)算法的文件压缩的实现(C语言)(原创)》

#include

#define MAX 100

void detect(char s[])
{
char ch[MAX];/*记录出现的字符*/
int num[MAX]={0};/*记录每个字符出现的次数*/
int i,j,n=0;
for(i=0;s[i]!='\0';i++)
{
for(j=0;j<n;j++)
if(s[i]==ch[j]||(ch[j]>='a'&&ch[j]<='z'&&s[i]+32==ch[j])) break;/*判断该字符是否已经出现过*/
if(j<n)/*该字符出现过,对应的记数器num[j]加一*/
num[j]++;
else/*该字符是新出现的字符,记录到ch[j]中,对应计数器num[j]加一*/
{
if(s[i]>='A'&&s[i]<='Z')
ch[j]=s[i]+32;
else
ch[j]=s[i];
num[j]++;
n++;/*出现的字符的种类数加1*/
}
}
for(i=0;i<n;i++)/*输出*/
printf("\'%c\'出现了%d次
",ch[i],num[i]);
}

main()
{
int i=0;
char s[MAX];
printf("请输入一个字符串:");
while((s[i]=getchar())!='
')/*输入*/
i++;
s[i]='\0';
detect(s);
}

一般是设置两个数组,一个数组便是字符,另一个数组表示权值即出现的次数,一一对应即可。

我这边有一份C语言的哈夫曼树的相关代码,以前从网上找的

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100
#define M 2*N-1
typedef char * HuffmanCode[2*M];//haffman编码
typedef struct
{
 int weight;//权值
 int parent;//父节节点
 int LChild;//左子节点
 int RChild;//右子节点
}HTNode,Huffman[M+1];//huffman树
typedef struct Node
{
 int weight; //叶子结点的权值
 char c; //叶子结点
 int num; //叶子结点的二进制码的长度
}WNode,WeightNode[N];
/***产生叶子结点的字符和权值***/
void CreateWeight(char ch[],int *s,WeightNode CW,int *p)
{
 int i,j,k;
 int tag;
 *p=0;//叶子节点个数
 //统计字符出现个数,放入CW
 for(i=0;ch[i]!='\0';i++)
 {
  tag=1;
  for(j=0;j<i;j++)
  {
   if(ch[j]==ch[i])
   {
    tag=0;
    break;
   }
  }
  if(tag)
  {
   CW[++*p].c=ch[i];
   CW[*p].weight=1;
   for(k=i+1;ch[k]!='\0';k++)
   {
    if(ch[i]==ch[k])
     CW[*p].weight++;//权值累加
   }
  }
 }
 *s=i;//字符串长度
}
/********创建HuffmanTree********/
void CreateHuffmanTree(Huffman ht,WeightNode w,int n)
{
 int i,j;
 int s1,s2;
 //初始化哈夫曼树
 for(i=1;i<=n;i++)
 {
  ht[i].weight =w[i].weight;
  ht[i].parent=0;
  ht[i].LChild=0;
  ht[i].RChild=0;
 }
 for(i=n+1;i<=2*n-1;i++)
 {
  ht[i].weight=0;
  ht[i].parent=0;
  ht[i].LChild=0;
  ht[i].RChild=0;
 }
 for(i=n+1;i<=2*n-1;i++)
 {
  for(j=1;j<=i-1;j++)
   if(!ht[j].parent)break;
  s1=j; //找到第一个双亲为零的结点
  for(;j<=i-1;j++)
   if(!ht[j].parent)
    s1=ht[s1].weight>ht[j].weight?j:s1;
  ht[s1].parent=i;
  ht[i].LChild=s1;
  for(j=1;j<=i-1;j++)
   if(!ht[j].parent)
    break;
  s2=j; //找到第二个双亲为零的结点
  for(;j<=i-1;j++)
   if(!ht[j].parent)
    s2=ht[s2].weight>ht[j].weight?j:s2;
  ht[s2].parent=i;
  ht[i].RChild=s2;
  ht[i].weight=ht[s1].weight+ht[s2].weight;//权值累加
 }
}
/***********叶子结点的编码***********/
void CrtHuffmanNodeCode(Huffman ht,char ch[],HuffmanCode h,WeightNode weight,int m,int n)
{
 int i,c,p,start;
 char *cd;
 cd=(char *)malloc(n*sizeof(char));
 cd[n-1]='\0';//末尾置0
 for(i=1;i<=n;i++)
 {
  start=n-1; //cd串每次从末尾开始
  c=i;
  p=ht[i].parent;//p在n+1至2n-1
  while(p) //沿父亲方向遍历,直到为0
  {
   start--;//依次向前置值
   if(ht[p].LChild==c)//与左子相同,置0
   cd[start]='0';
   else //否则置1
   cd[start]='1';
   c=p;
   p=ht[p].parent;
  }
  weight[i].num=n-start; //二进制码的长度(包含末尾0)
  h[i]=(char *)malloc((n-start)*sizeof(char));
  strcpy(h[i],&cd[start]);//将二进制字符串拷贝到指针数组h中
 }
 free(cd);//释放cd内存
 system("pause");
}
/*********所有字符的编码*********/
void CrtHuffmanCode(char ch[],HuffmanCode h,HuffmanCode hc,WeightNode weight,int n,int m)
{
 int i,k;
 for(i=0;i<m;i++)
 {
  for(k=1;k<=n;k++) /*从weight[k].c中查找与ch[i]相等的下标K*/
  if(ch[i]==weight[k].c)
  break;
  hc[i]=(char *)malloc((weight[k].num)*sizeof(char));
  strcpy(hc[i],h[k]); //拷贝二进制编码
 }
}
/*****解码*****/
void TrsHuffmanTree(Huffman ht,WeightNode w,HuffmanCode hc,int n,int m)
{
 int i=0,j,p;
 printf("***StringInformation***
");
 while(i<m)
 {
  p=2*n-1;//从父亲节点向下遍历直到叶子节点
  for(j=0;hc[i][j]!='\0';j++)
  {
   if(hc[i][j]=='0')
    p=ht[p].LChild;
   else
    p=ht[p].RChild;
  }
  printf("%c",w[p].c); /*打印原信息*/
  i++;
 }
}
/*****释放huffman编码内存*****/
void FreeHuffmanCode(HuffmanCode h,HuffmanCode hc,int n,int m)
{
 int i;
 for(i=1;i<=n;i++)//释放叶子结点的编码
  free(h[i]);
 for(i=0;i<m;i++) //释放所有结点的编码
  free(hc[i]);
}
//main
void main()
{
 int i,n=0; /*n为叶子结点的个数*/
 int m=0; /*m为字符串ch[]的长度*/
 char ch[N]; /*ch[N]存放输入的字符串*/
 Huffman ht; /*Huffman二叉数*/
 HuffmanCode h,hc; /*h存放叶子结点的编码,hc 存放所有结点的编码*/
 WeightNode weight; /*存放叶子结点的信息*/
 printf("***HuffmanCoding***
");
 printf("please input information :");
 gets(ch); /*输入字符串*/
 CreateWeight(ch,&m,weight,&n); /*产生叶子结点信息,m为字符串ch[]的长度*/
 printf("***WeightInformation***
 Node ");
 for(i=1;i<=n;i++) //输出叶子结点的字符与权值
  printf("%c ",weight[i].c);
 printf("
Weight ");
 for(i=1;i<=n;i++)
  printf("%d ",weight[i].weight);
 CreateHuffmanTree(ht,weight,n); //产生Huffman树
 printf("
***HuffamnTreeInformation***
");
 printf("iweightparentLChildRChild
");
 for(i=1;i<=2*n-1;i++) //打印Huffman树的信息
  printf("%d%d%d%d%d
",i,ht[i].weight,ht[i].parent,ht[i].LChild,ht[i].RChild);
 CrtHuffmanNodeCode(ht,ch,h,weight,m,n); //叶子结点的编码
 printf(" ***NodeCode***
"); //打印叶子结点的编码
 for(i=1;i<=n;i++)
 {
  printf("%c:",weight[i].c);
  printf("%s
",h[i]);
 }
 CrtHuffmanCode(ch,h,hc,weight,n,m); //所有字符的编码
 printf("***StringCode***
"); //打印字符串的编码
 for(i=0;i<m;i++)
 printf("%s",hc[i]);
 system("pause");
 TrsHuffmanTree(ht,weight,hc,n,m); //解码
 FreeHuffmanCode(h,hc,n,m);
 system("pause");
}



怎么给哈夫曼树设置字符以及其频度
一般是设置两个数组,一个数组便是字符,另一个数组表示权值即出现的次数,一一对应即可。我这边有一份C语言的哈夫曼树的相关代码,以前从网上找的 include <stdio.h>#include <stdlib.h>#include <string.h>#define N 100#define M 2*N-1typedef char * HuffmanCode[2*M];\/\/haffman编码typedef...

哈夫曼编码
以A、B、C、D、E五个字符为例,频率分别为5、4、3、2、1。构建哈夫曼树的步骤如下:首先选取最小权值的两个字符构造新树,接着将生成的新节点加入剩余集合,重复此过程直到所有字符都加入树中。最终得到的哈夫曼树如上图所示。根据哈夫曼树构建字符编码:A->11, B->10, C->00, D->011, ...

如何完成哈夫曼结点的初始化参数设置过程?
- 创建一个新的内部结点,将其频率设置为这两个结点的频率之和,并将这两个结点分别作为新结点的左子结点和右子结点。- 将新创建的内部结点插入到优先队列中。5. **设置哈夫曼编码**:从根结点开始,遍历哈夫曼树并为每个叶子结点分配一个二进制编码。向左走分配0,向右走分配1。完成上述过程后,...

数据结构(C语言)-哈夫曼(Huffman)树编码译码操作
实现上,哈夫曼树的结点和编码都采用顺序存储结构,如HuffNodes数组。首先,输入字符串并统计字符出现的频次,然后每次选取频率最小的两个结点合并,直至形成一棵哈夫曼树。通过递归遍历这棵树,我们可以生成每个字符的哈夫曼编码,例如字符A对应编码10,B为001,C为01,D为11,E为000。编码过程涉及编写e...

一棵哈弗曼树有n个节点,可以对几个字符编码
使用哈夫曼树来为每个字符分配一个二进制编码。哈

假设用于通信的电文仅由1234这4个字符组成,字符出现的频率为1:0.5、2...
建立哈夫曼树的步骤如下:将字符按照频率从小到大排序,每个字符可以看作一个权值为该字符频率的节点;选择两个权值最小的节点作为左右孩子节点,将它们的权值相加得到一个新节点的权值;将新节点加入到排序后的节点序列中,重新排序;重复步骤2-3,直到序列中只剩下一个节点,这个节点就是哈夫曼树的根...

构造以下实例的哈夫曼树 并给出你的哈夫曼字符编码
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其...

哈夫曼树哈夫曼树的应用
哈夫曼树的构建是将字符集中的每个字符作为叶子节点,以字符出现的频率作为权值。权值小的字符节点位置较低,从而形成编码长度与其频率成反比的结构。这样,频率高的字符用较短的编码,频率低的字符用较长的编码,确保了整体编码的最短长度。有两种主要的哈夫曼编码方法:静态编码和动态编码。静态编码需要...

最优二叉树算法编码和解码
而在解码阶段,我们需要依赖于哈夫曼树T。这个过程是这样的:从根节点T[m-1]开始,逐字节读取压缩文件中的二进制码。每次读取一个0,就沿着树的左分支前进;读取1,则向右分支移动。当我们遇到一个叶子节点T[i]时,就根据这个节点对应的H[i].ch取出相应的字符。然后,我们重新回到根节点,继续这个...

数据结构(14)-哈夫曼树&哈夫曼编码
图中红色字的结点即为原来的结点,黑色字的结点是新生成的结点。总结步骤如下:哈夫曼树被发明出来的主要目的是解决当年远距离通信的数据传输最优化的问题。比如需传送的电报为 BADCADFEED ,它只用到6种字符,我们可以使用对应的二进制数来进行表示:传输后的编码就是 001 000 011 010 000 011 101 ...

新和县15969861471: 建哈夫曼树及编码,例如:已知某系统在通讯网络中只可能出现8种字符(A、B、C、D、E、F、G、H),其频率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,... -
莘阀欣青:[答案] 步骤:一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空.(为方便在计算机上实现算 法,一般还要求...

新和县15969861471: 哈夫曼编码问题(有要求,请给完整程序)满足要求的追加 -
莘阀欣青: #include<iostream> using namespace std; class Knap { friend int Knapsack(int p[],int w[],int c,int n ); public: void print() { cout<<"最优解为:"<<endl; for(int m=1;m<=n;m++) cout<<bestx[m]<<" "; cout<<endl; } private: int Bound(int i); void ...

新和县15969861471: 3.给设定权值集w={5,4,7,9,2,6},分别代表{a,b,c,d,e,f}这六个字符出现的频率. -
莘阀欣青: //huffman二叉树#include<stdio.h>#include<stdlib.h> struct HTree { char c; int parent,lChild,rChild,w,s; }; struct stack { char Data[80]; int top; }; typedef struct HTree HTree; typedef struct stack stack;//栈的相关操作,哈夫曼编码的时候会用到 stack *...

新和县15969861471: 创建哈夫曼树时,如何根据输入字符串出现的频率对结点的权重进行赋值的?? -
莘阀欣青: #include <stdio.h>#define N 10 /*待编码字符的个数,即树中叶结点的最大个数*/#define M 2*N-1 /*树中总的结点数目*/ typedef struct { unsigned int weight;/* 用来存放各个结点的权值*/ unsigned int parent,lchild,rchild;/*指向双亲、孩子结点的指...

新和县15969861471: 数据结构 最优二叉树 -
莘阀欣青: 这是我们的作业题,自己写 的……(可能输入的格式跟你要的不一致,自己改一下) 如果有什么不懂的就问我,我可以把其中所有相关的文件发给你 ^^ 注:1、 初始化创建哈夫曼树有三种选择,其中选择编译课本测试数据时和编译源文件是,...

新和县15969861471: huffman编码算法 -
莘阀欣青: 哈夫曼是一种编码手段.也就是说保证将来的编码是最小长度的,最终生成最小的哈夫曼编码树,又称哈夫曼最小树.它的原理是将一段文本中出现的字符按出现的频率决定其编码.然后按其最终的编码生成一段明文.知道了这个原理,编码...

新和县15969861471: 如何用统计字符频率及构建哈夫曼树. -
莘阀欣青: 这里有个C写的,VC++6.0可以编译 《基于哈夫曼(haffuman)算法的文件压缩的实现(C语言)(原创)》http://hi.baidu.com/gropefor/blog/item/eff84a084cdcb4b82fddd47d.html

新和县15969861471: 哈夫曼树的建立 -
莘阀欣青: 给你个大概的代码,把显示跟调用那里改改#include #include #include#include typedef struct { unsigned int weight; unsigned int parent,lchild,rchild,ch; }HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树 typedef char *HuffmanCode; //动态分配...

新和县15969861471: 哈夫曼树 设计哈夫曼编码 -
莘阀欣青: a0.3,b0.2,c0.15,d0.1,e0.1,f0.05,g0.05,h0.05 a0.3,b0.2,c0.15,d0.1,e0.1,f0.05,(g,h)0.1 a0.3,b0.2,c0.15,d0.1,e0.1,(f,(g,h))0.15 a0.3,b0.2,c0.15,(d,e)0.2,(f,(g,h))0.15 a0.3,b0.2,(d,e)0.2,(c,(f,(g,h)))0.3 a0.3,(b,(d,e))0.4,(c,(f,(g,h)))0.3 (b,(d,e))0.4,(a(c,(f,(g,h)))...

新和县15969861471: 设字符集D={A,B,C,D,E},各字符使用频率W={10,2,5,6,4},画出对字符进行哈夫曼编码时所对应的哈夫曼树,并给出各字符的编码.是不是只有一种可能 -
莘阀欣青:[答案] 频率是W={10,2,5,6,4},你可以根据这个算出每个符号的使用概率.Huffman编码的基本思想就是:对于使用频率比较高的符号用较短的码字去编码,对于使用频率比较低的符号用较长的码字去编码,这样使得编码效率很高,即所编的...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网