哈夫曼的c语言实现代码

着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码
 

我们设置一个结构数组 HuffNode 保存哈夫曼树中各结点的信息。根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有 2n-1 个结点,所以数组 HuffNode 的大小设置为 2n-1 。HuffNode 结构中有 weight, lchild, rchild 和 parent 域。其中,weight 域保存结点的权值, lchild 和 rchild 分别保存该结点的左、右孩子的结点在数组 HuffNode 中的序号,从而建立起结点之间的关系。为了判定一个结点是否已加入到要建立的哈夫曼树中,可通过 parent 域的值来确定。初始时 parent 的值为 -1。当结点加入到树中去时,该结点 parent 的值为其父结点在数组 HuffNode 中的序号,而不会是 -1 了。

求叶结点的编码:
该过程实质上就是在已建立的哈夫曼树中,从叶结点开始,沿结点的双亲链域回退到根结 点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶结点所经过的路径上各分支所组成的 0、1 序列,因此先得到的分支代码为所求编码的低位,后得到的分支代码为所求编码的高位码。我们可以设置一个结构数组 HuffCode 用来存放各字符的哈夫曼编码信息,数组元素的结构中有两个域:bit 和 start。其中,域 bit 为一维数组,用来保存字符的哈夫曼编码, start 表示该编码在数组 bit 中的开始位置。所以,对于第 i 个字符,它的哈夫曼编码存放在 HuffCode[i].bit 中的从 HuffCode[i].start 到 n 的 bit 位中。

复制代码 代码如下:

/*-------------------------------------------------------------------------
 * Name:   哈夫曼编码源代码。
 * 在 Win-TC 下测试通过
 * 实现过程:着先通过 HuffmanTree() 函数构造哈夫曼树,然后在主函数 main()中
 *           自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在
 *           父结点左侧,则置码为 0,若在右侧,则置码为 1。最后输出生成的编码。
 *------------------------------------------------------------------------*/
#include <stdio.h>

#define MAXBIT      100
#define MAXVALUE  10000
#define MAXLEAF     30
#define MAXNODE    MAXLEAF*2 -1

typedef struct
{
    int bit[MAXBIT];
    int start;
} HCodeType;        /* 编码结构体 */
typedef struct
{
    int weight;
    int parent;
    int lchild;
    int rchild;
} HNodeType;        /* 结点结构体 */

/* 构造一颗哈夫曼树 */
void HuffmanTree (HNodeType HuffNode[MAXNODE],  int n)
{
    /* i、j: 循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,
        x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/
    int i, j, m1, m2, x1, x2;
    /* 初始化存放哈夫曼树数组 HuffNode[] 中的结点 */
    for (i=0; i<2*n-1; i++)
    {
        HuffNode[i].weight = 0;
        HuffNode[i].parent =-1;
        HuffNode[i].lchild =-1;
        HuffNode[i].lchild =-1;
    } /* end for */

    /* 输入 n 个叶子结点的权值 */
    for (i=0; i<n; i++)
    {
        printf ("Please input weight of leaf node %d: n", i);
        scanf ("%d", &HuffNode[i].weight);
    } /* end for */

    /* 循环构造 Huffman 树 */
    for (i=0; i<n-1; i++)
    {
        m1=m2=MAXVALUE;     /* m1、m2中存放两个无父结点且结点权值最小的两个结点 */
        x1=x2=0;
        /* 找出所有结点中权值最小、无父结点的两个结点,并合并之为一颗二叉树 */
        for (j=0; j<n+i; j++)
        {
            if (HuffNode[j].weight < m1 && HuffNode[j].parent==-1)
            {
                m2=m1;
                x2=x1;
                m1=HuffNode[j].weight;
                x1=j;
            }
            else if (HuffNode[j].weight < m2 && HuffNode[j].parent==-1)
            {
                m2=HuffNode[j].weight;
                x2=j;
            }
        } /* end for */
            /* 设置找到的两个子结点 x1、x2 的父结点信息 */
        HuffNode[x1].parent  = n+i;
        HuffNode[x2].parent  = n+i;
        HuffNode[n+i].weight = HuffNode[x1].weight + HuffNode[x2].weight;
        HuffNode[n+i].lchild = x1;
        HuffNode[n+i].rchild = x2;

        printf ("x1.weight and x2.weight in round %d: %d, %dn", i+1, HuffNode[x1].weight, HuffNode[x2].weight);  /* 用于测试 */
        printf ("n");
    } /* end for */
} /* end HuffmanTree */

int main(void)
{
    HNodeType HuffNode[MAXNODE];            /* 定义一个结点结构体数组 */
    HCodeType HuffCode[MAXLEAF],  cd;       /* 定义一个编码结构体数组, 同时定义一个临时变量来存放求解编码时的信息 */
    int i, j, c, p, n;
    printf ("Please input n:n");
    scanf ("%d", &n);
    HuffmanTree (HuffNode, n);

    for (i=0; i < n; i++)
    {
        cd.start = n-1;
        c = i;
        p = HuffNode[c].parent;
        while (p != -1)   /* 父结点存在 */
        {
            if (HuffNode[p].lchild == c)
                cd.bit[cd.start] = 0;
            else
                cd.bit[cd.start] = 1;
            cd.start--;        /* 求编码的低一位 */
            c=p;                   
            p=HuffNode[c].parent;    /* 设置下一循环条件 */
        } /* end while */

        /* 保存求出的每个叶结点的哈夫曼编码和编码的起始位 */
        for (j=cd.start+1; j<n; j++)
        { HuffCode[i].bit[j] = cd.bit[j];}
        HuffCode[i].start = cd.start;
    } /* end for */

    /* 输出已保存好的所有存在编码的哈夫曼编码 */
    for (i=0; i<n; i++)
    {
        printf ("%d 's Huffman code is: ", i);
        for (j=HuffCode[i].start+1; j < n; j++)
        {
            printf ("%d", HuffCode[i].bit[j]);
        }
        printf ("n");
    }
    getch();
    return 0;
}

时间: 2024-10-26 05:54:26

哈夫曼的c语言实现代码的相关文章

哈夫曼的c语言实现代码_C 语言

我们设置一个结构数组 HuffNode 保存哈夫曼树中各结点的信息.根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有 2n-1 个结点,所以数组 HuffNode 的大小设置为 2n-1 .HuffNode 结构中有 weight, lchild, rchild 和 parent 域.其中,weight 域保存结点的权值, lchild 和 rchild 分别保存该结点的左.右孩子的结点在数组 HuffNode 中的序号,从而建立起结点之间的关系.为了判定一个结点是否已加入到要建立的哈夫曼树

哈夫曼编码问题 语言-求大神更正一下哈夫曼编码,重谢!

问题描述 求大神更正一下哈夫曼编码,重谢! #include #include #include static float weights[]={12.702 ,9.056 ,8.167 ,7.507 ,6.966 ,6.749 ,6.327 , 6.094 ,5.987 ,4.253 ,4.025 ,2.782 ,2.758 ,2.406 , 2.360 ,2.228 ,2.105 ,1.974 ,1.929 ,1.492 ,0.978 , 0.722 ,0.153 ,0.150 ,0.095

c-VC6.0++中如何对一组数据进行哈夫曼编码

问题描述 VC6.0++中如何对一组数据进行哈夫曼编码 C[ ]中有256个概率,将他们哈夫曼编码.然后做成个函数来调用 void Hoffuman(double* P,long* Output,long* Len) { } 解决方案 哈夫曼的c语言实现代码 解决方案二: (在VC++上调试通过)哈夫曼树编码上机实验 Google 查找:数组 C++ 哈夫曼编码 解决方案三: (在VC++上调试通过)哈夫曼树编码上机实验 Google 查找:数组 C++ 哈夫曼编码 解决方案四: http://

求一段可以打印哈夫曼树的代码,能够在执行时看到的,谢谢!!

问题描述 求一段可以打印哈夫曼树的代码,能够在执行时看到的,谢谢!! 求一段可以将我写的哈夫曼树打印出来的代码,谢谢!!我正在写一个huffman的编码和译码的程序可是不会写打印的,请大家帮忙 解决方案 http://blog.csdn.net/creazyapple/article/details/7948207http://blog.csdn.net/skyline0623/article/details/6023443 解决方案二: 注意调用方法,把指向树的指针传给第二个函数: void

C++实现哈夫曼树简单创建与遍历的方法_C 语言

本文以实例形式讲述了C++实现哈夫曼树简单创建与遍历的方法,比较经典的C++算法. 本例实现的功能为:给定n个带权的节点,如何构造一棵n个带有给定权值的叶节点的二叉树,使其带全路径长度WPL最小. 据此构造出最优树算法如下: 哈夫曼算法: 1. 将n个权值分别为w1,w2,w3,....wn-1,wn的节点按权值递增排序,将每个权值作为一棵二叉树.构成n棵二叉树森林F={T1,T2,T3,T4,...Tn},其中每个二叉树都只有一个权值,其左右字数为空 2. 在森林F中选取根节点权值最小二叉树,

哈夫曼算法构造代码_C 语言

1.定义 哈夫曼编码主要用于数据压缩. 哈夫曼编码是一种可变长编码.该编码将出现频率高的字符,使用短编码:将出现频率低的字符,使用长编码. 变长编码的主要问题是,必须实现非前缀编码,即在一个字符集中,任何一个字符的编码都不是另一个字符编码的前缀.如:0.10就是非前缀编码,而0.01不是非前缀编码. 2.哈夫曼树的构造 按照字符出现的频率,总是选择当前具有较小频率的两个节点,组合为一个新的节点,循环此过程知道只剩下一个节点为止. 对于5个字符A.B.C.D.E,频率分别用1.5.7.9.6表示,

c语言-只出现C,A,S,T,B五种字符,它们出现的频率依次是2,4,2,3,3,试设计哈夫曼编码

问题描述 只出现C,A,S,T,B五种字符,它们出现的频率依次是2,4,2,3,3,试设计哈夫曼编码 已知某系统在通讯时,只出现C,A,S,T,B五种字符,它们出现的频率依次是2,4,2,3,3,试设计哈夫曼编码 求C语言代码,谢大神帮助 解决方案 这是答案,但代码需要自己编写 解决方案二: 可参考 http://wenku.baidu.com/link?url=I6i3SKAdz4-e56zOCBwzdRvXAv4ERrXA47b9-eVwKCQFexD2pT6AUIGTd3QE6jXqiF1

c语言-C语言文件/哈夫曼树/算法/二叉树

问题描述 C语言文件/哈夫曼树/算法/二叉树 在一个函数中,下面这两行运行无错误 fp=fopen("CodeFile.dat","wb"); fwrite(HC[i],sizeof(char),strlen(HC[i])+1,fp); //其中HC的类型是char ** //然后在另外一个函数中加入 fp=fopen("CodeFile.dat","rb"); for(int i=1;i<=n;i++) fread(H

解析C++哈夫曼树编码和译码的实现_C 语言

一.背景介绍: 给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近. 二.实现步骤: 1.构造一棵哈夫曼树 2.根据创建好的哈夫曼树创建一张哈夫曼编码表 3.输入一串哈夫曼序列,输出原始字符 三.设计思想: 1.首先要构造一棵哈夫曼树,哈夫曼树的结点结构包括权值,双亲,左右孩子:假如由n个字符来构造一棵哈夫曼树,则共有结点2n-1个:在构造前,先初始化