#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 100
#define M 2*N-1
typedef char *HuffmanCode[2*M];
typedef struct
{
 int weight;//权值
 int parent;//父节点
 int Lchild;//左
 int Rchild;//右
}HTNode,Huffman[M+1];//huffman树
typedef struct Node
{
 int weight;//叶子权值
 char c;//叶子
 int num;//叶子的2进制码长度
}WNode,WeightNode[N];
void CreatWeight(char ch[],int *s,WeightNode CW,int *p)//生成叶子节点字符与权值
{
 int i,j,k;
 int tag;
 *p=0;//叶子节点数
 for(i=0;ch[i]!='\0';i++)//记录字符个数放入CW
 {
  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;//字符串长
}
void CreateHuffmanTree(Huffman ht,WeightNode w,int n)//建立huffmantree
{
 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;//找第一个双亲!=0节点
   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;//找第二个双亲!=0节点
     for(;j<=i-1;j++)
      if(!ht[j].parent)
       s2=ht[s2].weight>ht[j].weight?j:s2;
    //  printf("s2=%d\n",s2);
      ht[s2].parent=i;
      ht[i].Rchild=s2;
               //  intf("rchild=%d\n",ht[i].Rchild);
      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)//与lchild相同=0
    cd[start]='0';
   else//=1
    cd[start]='1';
   c=p;
   p=ht[p].parent;
  }
  weight[i].num=n-start;//二进制码长度
  h[i]=(char*)malloc((n-start)*sizeof(char));
  strcpy(h[i],&cd[start]);//二进制字符复制到h
 }
 free(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;
 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++;
 }
}
void main()
{
 int i;
 int n=0;//叶子数
 int m=0;//ch长度
 char ch[N];//输入字符
 Huffman ht;//huffman二叉树
 HuffmanCode h;//叶子编码
 HuffmanCode hc;//所有节点编码
 WeightNode weight;//叶子信息
 printf("Huffman\n  please intput inf\n");
 gets(ch);
 CreatWeight(ch,&m,weight,&n);
 for(i=1;i<=n;i++)//输出叶子字符和权
  printf("%c",weight[i].c);
 printf("\nweight");
 for(i=1;i<=n;i++)
  printf("%d",weight[i].weight);
 CreateHuffmanTree(ht,weight,n);
 printf("\ti\tweight\tparent\tLChild\tRChild\n");
 for(i=1;i<=2*n-1;i++)
  printf("\t%d\t%d\t%d\t%d\t%d\n",i,ht[i].weight,ht[i].parent,ht[i].Lchild,ht[i].Rchild);
 CrtHuffmanNodeCode(ht,ch,h,weight,m,n);
 for(i=1;i<=n;i++)
 {
  printf("\t%c ",weight[i].c);
  printf("%s\n",h[i]);
 }
 CrtHuffmanCode(ch,h,hc,weight,n,m);
 printf("code");
 for(i=0;i<m;i++)
  printf("%s",hc[i]);
 printf("\n");
 TrsHuffmanTree(ht,weight,hc,n,m);
}

haffman树c实现的更多相关文章

  1. Haffman编码(haffman树)

    Haffman编码 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去...).现在给你一串字符以及它们所对应的权值 ...

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

    哈夫曼树 哈夫曼树也叫最优二叉树(哈夫曼树) 问题:什么是哈夫曼树? 例:将学生的百分制成绩转换为五分制成绩:≥90 分: A,80-89分: B,70-79分: C,60-69分: D,<60 ...

  3. java实现Haffman编码

    1.先创建一个树节点类(泛型类),为了方便使用集合的排序方法,泛型类要实现泛型接口Comparable,代码如下 package com.hjp.huffman; /** * Created by J ...

  4. 文件压缩小项目haffman压缩

    文件压缩的原理: 文件压缩总体可以分为有损压缩和无损压缩两类,有损压缩是指对mp3等格式的文件,忽略一些无关紧要的信息,只保留一些关键的信息,但并不因此影响用户对于这些mp3格式文件的体验度,无损压缩 ...

  5. Huffman Tree

    哈夫曼(Huffman)树又称最优二叉树.它是一种带权路径长度最短的树,应用非常广泛. 关于Huffman Tree会涉及到下面的一些概念: 1. 路径和路径长度路径是指在树中从一个结点到另一个结点所 ...

  6. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

  7. [数据结构] 大纲 - Stan Zhang 数据结构速通教程

    * 注: 本文/本系列谢绝转载,如有转载,本人有权利追究相应责任. 2019年4月8日 P1.1 链表 Link:https://www.cnblogs.com/yosql473/p/10727471 ...

  8. JPEG编码(二)

    来自CSDN评论区http://bbs.csdn.net/topics/190980 1. 色彩模型 JPEG 的图片使用的是 YCrCb 颜色模型, 而不是计算机上最常用的 RGB. 关于色彩模型, ...

  9. c++实验8 哈夫曼编码-译码器

    哈夫曼编码-译码器 此次实验的注释解析多加不少---若对小伙伴们有帮助 希望各位麻烦点个关注 多谢 1.哈夫曼树构造算法为: (1)由给定的n个权值{w1,w2,…,wn}构造n棵只有根结点的二叉树, ...

随机推荐

  1. LinkedIn第三方登录

    官方开发文档网址:https://developer.linkedin.com angularjs LinkedIn初始化 var apiKey='77n7z65hd7azmb';$(function ...

  2. c++ Cout 输出格式

    控制符是在头文件iomanip.h中定义的对象.使用前必须把iomanip.h包含进来 1. I/O的书写格式 I/0流是输入或输出的一系列字节,当程序需要在屏幕上显示输出时,可以使用插入操作符“&l ...

  3. PIL安装记录,编译支持jpeg png

    PIL是python理想的图片处理module,但是想要良好的支持各种图片,还需要检查一下几步,否则会提示:IOError: decoder jpeg not available之类的. 我的环境:L ...

  4. CoreBluetooth

    Core Bluetooth的基本常识 每个蓝牙4.0设备都是通过服务(Service)和特征(Characteristic)来展示自己的 一个设备必然包含一个或多个服务,每个服务下面又包含若干个特征 ...

  5. POJ刷题记录 (。・`ω´・)(Progress:6/50)

    1743:前后作差可以转化成不可重叠最长公共字串问题,运用后缀数组解决(参考罗穗骞神犇的论文) #include <cstdio> #include <cstring> #in ...

  6. 仿小米网jQuery全屏滚动插件fullPage.js

    演 示 下 载   简介 如今我们经常能见到全屏网站,尤其是国外网站.这些网站用几幅很大的图片或色块做背景,再添加一些简单的内容,显得格外的高端大气上档次.比如 iPhone 5C 的介绍页面,QQ浏 ...

  7. 不使用ASP.NET服务器端控件(包括form表单不加runat="server")来触发.cs里的事件(方法),(适用于有代码洁癖者)。

    很多时候,我们使用服务器端控件写出的代码,会给我们生成一些很多我们看不懂的代码(初学者),但是有时候我们并不需要这些代码(业务需求不同),对于生成的一些代码感到多余.所以我就开始想,有没有一种可能:不 ...

  8. python - StringIO文本缓冲

    参考:http://pymotwcn.readthedocs.org/en/latest/documents/StringIO.html 类StringIO提供了一个在内存中方便处理文本的类文件(读, ...

  9. 移动Web开发,4行代码检测浏览器是否支持position:fixed

    不废话,直接上代码 var div = document.createElement('div'); div.style.cssText = 'display:none;position:fixed; ...

  10. Cookie的基本使用

    1, 如何创建cookie <?php //创建cookie信息 //这个函数用于保存cookie //第一个参数,表示cookie一个key,第二个表示val,第三个表示cookie值,在客户 ...