哈夫曼译码器

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define N 27
#define TYPE int
typedef struct
{
  TYPE w;
  int f,l,r;
}HNode,*Htree;
typedef struct
{
  char c;
  char code[10];
}Hcode, *Huffman;

void creat_HuffmanTree(HNode HT[],char ch[],int n1 )//n1为树节点数
{
  int i,j;
  TYPE low1,low2;
  int p1=0,p2=0;        //初始化p1,p2
  for ( i=N+1; i<=n1; i++ )
  {
    low1=999,low2=999;
    for ( j=1;j<i;j++)
    {

      if ( HT[j].f==0 && HT[j].w<low1)
      {
        low1=HT[j].w;
        p1=j;
      }
    }
    for ( j=1;j<i;j++)
      if ( HT[j].f==0 && HT[j].w<low2 &&  j!=p1 )
      {
        low2=HT[j].w;
        p2=j;
      }

    HT[p1].f=i;
    HT[p2].f=i;
    HT[i].l=p1;
    HT[i].r=p2;
    HT[i].w=low1+low2;
  }
}
void creat_Huffmancoding( HNode HT[],Hcode HC[],char ch[],int n1,int n2)//n1为树节点数,n2为符号个数
{             //左1右0
  int i,j,m,ff;
  char tmp[20];
  for ( i=1;i<=n2;i++ )
  {
    ff=i;
    j=0;
    while ( HT[ff].f!=0 )
    {

      if ( HT[ HT[ff].f ].l==ff)
        tmp[j++]='1';
      else tmp[j++]='0';
      ff=HT[ff].f;
    }
    tmp[j]='\0';
    HC[i].c =ch[i];      //字符下标从1开始
    for ( m=0;m<j;m++ )
      HC[i].code[m]=tmp[j-1-m];
    HC[i].code[m]='\0';
  }
}
void ECode(Hcode HC[])
{
  int i=0,j;
  char ss[100];
  gets(ss);
  while ( i<(int)strlen(ss) )
  {
    for ( j=1;j<=N;j++ )  //N为HC下标
     if (HC[j].c==ss[i])
     {
      printf ("%s ",HC[j].code);
      break;
     }
     if (j>N)
      printf ("ERROR ");
    i++;
  }
  printf ("\n");  

}
void DCode(Hcode HC[N+1])
{
  char ss[100];
  int i,j,m,k[N+1]={0},maxlen=0,tmp[N+1][N+1]={0};//tmp   几位字符,存放地址
  int begin,l,flag;
  char st[N+1];
  for ( i=1;i<=N;i++ )
  {
    j=strlen(HC[i].code);
    tmp[j][k[j]++]=i;
    if (j>maxlen)
     maxlen=j;
  }
  gets(ss);
  for ( begin=0;begin<(int)strlen(ss);)
  {
     for ( flag=l=0,j=begin;j<begin+maxlen;j++,l++ )
     {
     st[l]=ss[j];
     st[l+1]='\0';
     for ( m=0;m<k[j-begin+1];m++ )
     if (memcmp(st,HC[tmp[j-begin+1][m]].code,strlen(st) )==0)
     {
       printf ("%c",HC[tmp[j-begin+1][m]].c);
       flag=1;
       break;
     }
     if (flag==1){
          begin+=l+1;
          break;
        }
     }
    if (flag==1) flag=0;
     else printf("ERROE ");
  }
  printf ("\n");
}
int main()
{
  int i,k;
  char ch[N+1]={'0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' '};
  TYPE n[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27};         //默认权值
  HNode HT[2*N];
  Hcode HC[N+1];  

  for ( i=1;i<=N;i++ )
  {
    HT[i].w=n[i-1];
  }
  for ( i=1;i<=2*N;i++)      //结构体数据f,l,r,w初始化
   HT[i].f=HT[i].l =HT[i].r =0;

  creat_HuffmanTree (HT,ch,2*N-1);
  creat_Huffmancoding (HT,HC,ch,2*N-1,N);
  printf ("________________最短编码__________________________________________\n");
  printf ("_____1· 26个小写字母和空格进行赫夫曼编码_____________________________\n");
  printf ("_____2· 输入一个英文句子,输出其编码    _______________________________\n");
  printf ("_____3· 输入一个01序列,输出原文        ________________________________\n");
  printf ("_________________________________________________________________\n");
        printf ("输入序列号:");
  while(scanf ("%d",&k)&&  k!=0)
  { getchar();
   switch (k)
   {
   case 1:for ( i=1;i<=N;i++)
       {
      printf ("%c  %8s\t",HC[i].c,HC[i].code);
      if (!i%5)printf ("\n");
       }printf ("\n");
     break;
   case 2:ECode(HC);break;
   case 3:DCode(HC);break;
   default:        break;

   }
  }

  return 0;
}
时间: 2024-10-26 00:44:33

哈夫曼译码器的相关文章

哈夫曼(huffman)树和哈夫曼编码

哈夫曼树 哈夫曼树也叫最优二叉树(哈夫曼树)    问题:什么是哈夫曼树? 例:将学生的百分制成绩转换为五分制成绩:≥90 分: A,80-89分: B,70-79分: C,60-69分: D,<60分: E. if (a < 60){ b = 'E'; } else if (a < 70) { b = 'D'; } else if (a<80) { b = 'C'; } else if (a<90){ b = 'B'; } else { b = 'A'; } 判别树:用于描

HDU2527 构建哈夫曼树的灵巧运用

上课老师说了知道哈夫曼树叶子 不构图求二叉树的权 就是在构造哈夫曼树的时候运用构图的方法 把 每个结点的值加起来就是该数的权 证明 W=∑叶子权*该叶子层数 除了叶子的结点和就是这个树的权  构造一个树就知道了 结点的权 肯定是下一层结点的和 就好像  W=∑叶子权*该叶子层数 这个公式运用了 乘法分配律一样=  =  #include <iostream> #include<cstdio> #include<cstring> #include<algorithm

数据结构——赫夫曼树

1 基本概念 赫夫曼树(Huffman Tree)又称为最优树,是一类带权路径长度最短的树.本文仅讨论最优二叉树. 树的路径长度是指从树根到树中其余各个结点的路径长度之和.对具有n个结点的二叉树而言,完全二叉树具有最短的树的路径长度. 若在二叉树中,树叶结点带有权值,则有:结点的带权路径长度定义为从树根到该结点之间的路径长度与该结点上所带权值之积. 若树中有n个树叶结点,且每个树叶结点均带有权值,则有:树的带权路径长度定义为树中所有树叶结点的带权路径长度之和,可记为: 有时,也将树的路径长度称为

关于哈夫曼编码的程序运行时出错,我分析是由于cd定义出现了问题,导致后边cd[--start]出错

问题描述 关于哈夫曼编码的程序运行时出错,我分析是由于cd定义出现了问题,导致后边cd[--start]出错 void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){ //w存放n个字符的权值(均>0),构造赫夫曼树 HT,并求出n个字符的赫夫曼编码 HC printf("123"); system("pause"); int s1,s2,i,start; int f=0

简单快速的哈夫曼编码

介绍 本文描述在网上能够找到的最简单,最快速的哈夫曼编码.本方 法不使用任何扩展动态库,比如STL或者组件.只使用简单的C函数,比如: memset,memmove,qsort,malloc,realloc和memcpy. 因此,大家都会发现 ,理解甚至修改这个编码都是很容易的. 背景 哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件.哈夫 曼压缩属于可变代码长度算法一族.意思是个体符号(例如,文本文件中的字符 )用一个特定长度的位序列替代.因此,在文件中出现频率高的符号,使用短的 位序

哈夫曼树以及哈夫曼编码

哈夫曼树简介 哈夫曼树(哈夫曼树),又称最优二叉树,是一类带权路径长度最短的树.假设有n个权值{w1,w2,...,wn},如果构造一棵有n个叶子节点的二叉树,而这n个叶子节点的权值是{w1,w2,...,wn},则所构造出的带权路径长度最小的二叉树就被称为哈夫曼树. 这里补充下树的带权路径长度的概念.树的带权路径长度指树中所有叶子节点到根节点的路径长度与该叶子节点权值的乘积之和,如果在一棵二叉树中共有n个叶子节点,用Wi表示第i个叶子节点的权值,Li表示第i个也叶子节点到根节点的路径长度,则该

大话数据结构十六:哈夫曼树(最优二叉树)

1. 引子 当前素质教育的背景下,小学的学科成绩都改为了优秀.良好.及格.不及格这样的模糊词语,而不再通报具体的分数. 用代码可以表示如下: if( a < 60 ) System.out.print("不及格"); else if( a < 70 ) System.out.print("及格"); else if( a < 90 ) System.out.print("良好"); else System.out.print(&

哈夫曼树(三) Java详解

哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树.这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答. (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. 例子:100和80的路径长度是

哈夫曼树(二) C++详解

哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树.这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答. (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1. 例子:100和80的路径长度是