`
jaychang
  • 浏览: 734727 次
  • 性别: Icon_minigender_1
  • 来自: 嘉兴
社区版块
存档分类
最新评论

哈弗曼树建立与哈弗曼编码

阅读更多
#include<iostream>

#define LEN sizeof(HaffmanNode)
#define MAXSIZE 100
#define MAX 9999

using namespace std;

typedef struct{
  int value;
  int lChild,rChild,parent;
}HaffmanNode,Haffman[MAXSIZE];

typedef struct{
  char name;
  int w;
  char code[MAXSIZE];
}HaffmanCode[MAXSIZE];

//全局变量
Haffman h;
HaffmanCode hc;

//筛选出值最小的两个结点,s1,s2存储其结点的索引位置
void Select(Haffman h,int index,int *s1,int *s2)
{
  *s1=0;*s2=0;
  for(int i=1;i<=index;i++)
  {
   //筛选出无双亲结点,且权值最小的两个结点
    if(h[i].parent==0)
    {
      if(h[i].value<=h[*s1].value)
      {  
         *s2=*s1;
         *s1=i;
      }
      else if(h[i].value<h[*s2].value)
      {
         *s2=i;
       }
     }
  }
}

//创建哈弗曼树及每个叶结点的哈弗曼编码
void CreateHaffmanTree(Haffman h,HaffmanCode hc,int n)
{
  int s1,s2;
  h[0].value=MAX;
  for(int i=1;i<=n;i++)
  {
     h[i].lChild=h[i].rChild=h[i].parent=0;
     h[i].value=hc[i].w;
  }
  for(i=n+1;i<=2*n-1;i++)
  {
      h[i].lChild=h[i].rChild=h[i].parent=h[i].value=0;
   }

  //构建叶子结点外的其他结点
  for(i=n+1;i<=2*n-1;i++)
  { 
     Select(h,i-1,&s1,&s2);
     h[i].lChild=s1;h[i].rChild=s2;
     h[i].value=h[s1].value+h[s2].value;
     h[s1].parent=i;h[s2].parent=i;
  }
}

//求每个叶结点的哈弗曼编码
void CreateHaffmanCode(Haffman h,HaffmanCode hc,int n)
{
  int Stack[MAXSIZE],top=-1;
  char flag[MAXSIZE],j;         
  HaffmanNode th;
  for(int i=1;i<=n;i++)
  {
     th=h[i];int c=i;j=0;
     while(th.parent!=0)
     {
      Stack[++top]=th.parent;
      if(h[Stack[top]].lChild==c)
      {
        flag[top]='L';c=th.parent;
      }
      else if(h[Stack[top]].rChild==c)
      {
        flag[top]='R';c=th.parent;
      }
      th=h[Stack[top]];
   }
   while(top!=-1)
   {
     if(flag[top]=='L')
       hc[i].code[j++]='0';
     else
       hc[i].code[j++]='1';
     top--;
    }
    hc[i].code[j]='\0';
  }
}

//求叶结点的所在层的深度
int Depth(Haffman h,HaffmanNode hd)
{
  int count=0;
  HaffmanNode temp;
  temp=hd;
  while(temp.parent!=0)
  {
     temp=h[temp.parent];
     count++;
  }
  return count;
}

//打印叶结点的哈弗曼编码值,以及二叉树的带权路径长度
void PrintHaffmanCode(Haffman h,HaffmanCode hc,int n)
{
  int weight,sum=0;
  for(int i=1;i<=n;i++)
  {
     weight=Depth(h,h[i])*h[i].value;
     cout<<"结点名称:"<<hc[i].name<<",结点的哈弗曼编码值:"<<hc[i].code<<"\n";
     sum+=weight;
  }
  cout<<"带权路径长度为:"<<sum<<"\n";
}

int main()
{
  int n;
  char cmd;
  do{
     cout<<"输入叶子结点数目\n";
     cin>>n;
     cout<<"输入叶子结点名称和每个叶子结点的权值\n";
     for(int i=1;i<=n;i++)
    {
      cin>>hc[i].name>>hc[i].w;
     }
     CreateHaffmanTree(h,hc,n);
     CreateHaffmanCode(h,hc,n);
     PrintHaffmanCode(h,hc,n);
     cout<<"继续吗y/Y\n";
     cin>>cmd;
  }while(cmd=='y'||cmd=='Y');
  return 0;
}
 
分享到:
评论

相关推荐

    哈弗曼树的建立及哈弗曼编码的生成 c++实现

    5. **编码与解码**:编码阶段将字符映射到对应的哈弗曼编码,形成编码表;解码阶段则根据编码表反向解析二进制流得到原始字符。 在"哈夫曼树的实现"这个文件中,很可能包含了具体的C++代码实现,包括以上提到的各个...

    哈弗曼树的建立 C++代码

    - **编码生成**:哈弗曼编码的生成是构建哈弗曼树的重要后续步骤,但给定代码并未涉及。 - **性能优化**:使用优先队列(如C++ STL中的`priority_queue`)替换循环查找最小权重节点的过程,可以显著提高构建哈弗曼树...

    哈弗曼树 哈弗曼编码 译码

    哈弗曼编码译码 哈弗曼树的建立,编码 对26个大写英文字母以及空格键的编码,译码

    用哈弗曼树对文件进行编码和译码

    哈弗曼树的编码和译码过程可以分为三个步骤:读取文件、建立哈弗曼树和编码/译码。 首先,读取文件,统计每个字符的出现频次,并将其存储在一个数组中。然后,使用这些统计结果建立哈弗曼树。哈弗曼树是一种二叉树...

    哈弗曼编码 哈弗曼树 数据结构实习

    哈弗曼编码完成后,可以建立一个编码表,其中包含每个字符及其对应的哈弗曼编码。这个编码表用于解码过程,使得接收到的二进制码能够还原成原始字符。同时,为了可视化编码过程,可以使用图形化工具动态展示哈弗曼树...

    C++哈弗曼树

    哈弗曼树的构建基于以下两个核心概念:哈弗曼编码(Huffman Coding)和带权路径长度(Weighted Path Length)。哈弗曼编码是一种前缀编码,即没有任何一个编码是另一个编码的前缀,这样可以避免在解码时产生歧义。...

    C++实现哈弗曼树的建立

    ### C++ 实现哈夫曼树的建立 #### 概述 哈夫曼树(Huffman Tree),又称最优二叉树,是一种带权路径长度最短的二叉树,在数据压缩编码、文件系统等方面有着广泛的应用。本文将详细介绍如何利用 C++ 来实现哈夫曼树...

    哈弗曼树哈弗曼树哈弗曼树哈弗曼树

    2. **建立编码表**:对所有字符进行上述操作,形成一个哈弗曼编码表,用于编码和解码。 在解码时,我们需要根据已知的哈弗曼编码表,按二进制位读取输入流,遇到前缀匹配的编码,就识别出对应的字符。 在"哈弗曼...

    哈弗曼树编码译码

    2. 将编码与字符对应,形成编码表。 解码过程: 1. 从接收到的二进制码开始,按照哈夫曼编码表,根据0或1的序列决定向左还是向右移动,直到找到一个叶子节点,这个叶子节点对应的字符就是解码出的字符。 2. 重复此...

    哈弗曼编码器 并以直观方式显示哈弗曼树

    通过本次实验,不仅深入理解了哈弗曼编码的原理与实现过程,还掌握了如何构建和使用哈弗曼树进行数据编码和解码的技术。此外,通过实际操作,熟悉了数据结构的运用和文件操作的基本方法,对于提升编程能力和算法理解...

    哈弗曼编码

    哈弗曼树 哈弗曼编码 构造哈弗曼编码 建立哈弗曼树 编码

    数据结构 哈弗曼编码

    【哈弗曼编码】是一种高效的前缀编码方法,主要用于数据压缩。它的基本思想是通过...在实际应用中,哈弗曼编码常与其他数据压缩算法结合,如LZ77(Lempel-Ziv)和LZW(Lempel-Ziv-Welch)等,以进一步提高压缩效率。

    哈弗曼树的建立以及相关操作

    总的来说,哈弗曼树是一种高效的数据结构,利用结构体实现哈弗曼树的建立和操作是理解和实践数据结构与算法的重要环节。通过熟练掌握哈弗曼树的构建和相关操作,我们能更好地理解和应用数据压缩原理,提高程序的性能...

    哈弗曼树实验编码 有五个功能

    1. **建立哈弗曼树**: 这个功能是构建哈弗曼树的基础。首先,我们需要一个频率表,其中包含了每个字符或数据元素出现的频次。然后,通过一系列合并操作,将具有最小频率的节点合并成新的节点,直到所有节点合并为...

    数据结构_哈弗曼树编码.pdf

    在实际应用中,哈弗曼编码可以用于文本压缩,通过建立字符与短编码的映射关系,减少表示文本所需的位数,从而达到节省存储空间的效果。此外,哈弗曼编码也常用于通信传输,因为较短的编码可以提高传输效率。 总结来...

    哈弗曼编码译码器的实现

    在这个项目中,学生需要实现哈弗曼树的建立,以及基于哈弗曼编码的文件压缩和解压缩功能。以下是关于这个主题的详细知识讲解: 1. **哈弗曼树(Huffman Tree)**:哈弗曼树是一种特殊的二叉树,也称为最优二叉树。...

    哈弗曼树的建立,以及编/译码的实现

    哈弗曼编码的生成基于哈弗曼树的结构,遵循以下规则: - **左分支代表0**:从根节点出发,向左分支走一步表示在编码中添加一个0。 - **右分支代表1**:向右分支走一步表示添加一个1。 - **到达叶节点**:当到达叶...

    哈弗曼树的生成和编码的相关信息

    测试数据可以按照给出的字符集和频度来建立哈弗曼树,并对特定的字符串进行编码和解码。例如,字符`A`的频率为64,`N`的频率为57,以此类推,根据这些频率生成哈弗曼树,然后编码字符串中的每一个字符。 总的来说,...

    哈弗曼编码译码(C++实现,源码+可执行程序+实验报告)

    - 从接收到的位流中读取哈弗曼编码,根据哈弗曼树进行译码。在二叉树中,从根节点出发,根据位流中的0和1选择左或右子节点,当到达叶子节点时,该叶子节点对应的字符就是解码的结果。 5. **C++实现**: - 在C++中...

Global site tag (gtag.js) - Google Analytics