zoukankan      html  css  js  c++  java
  • 赫夫曼树编码问题

    定义:

      结点的带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积。树的带权路径长度为树中所有叶子结点的带权路径长度之和。假设有n个权值,试构造一棵有n个叶子结点的二叉树,每个叶子结点带权为wi,则其中带权路径长度最小的二叉树称做最优二叉树或赫夫曼树。 

     构造赫夫曼树的方法:  

    (1)根据给定的n个权值{w1,w2,w3......}构成n棵二叉树的集合F={T1,T2,T3,T4......},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均空。

    (2)在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。

    (3)在F中删除这两棵树,同时将新得到的二叉树加入F中。

    (4)重复(2)和(3),直到F只含一棵树为止。这棵树便是赫夫曼树。

    代码实现:

    #include<iostream>
    #include
    <assert.h>
    using namespace std;

    struct HuffmanNode
    {
    unsigned
    int weight;
    unsigned
    int parent,leftChild,rightChild;
    HuffmanNode()
    {
    weight
    =0;parent=0;leftChild=0;rightChild=0;
    }
    };

    void Select(const HuffmanNode* & nodelist,const int length,int & a, int &b)
    {
    int min=1000000,min2=1000000;
    for(int i=0;i<length;i++)
    {
    if(min>nodelist[i].weight&&nodelist[i].parent==0)
    {
    min
    =nodelist[i].weight;
    a
    =i;
    }
    }
    for(int j=0;j<length;j++)
    {
    if(j!=a&&min2>nodelist[j].weight&&nodelist[j].parent==0)
    {
    min2
    =nodelist[j].weight;
    b
    =j;
    }
    }
    }

    char ** HuffmanCoding(const int *w, const int n)
    {
    assert(w
    !=NULL);
    int i,min1,min2;
    int m = 2*n-1;
    HuffmanNode
    * nodelist = new HuffmanNode[m]();
    for(i=0;i<n;i++)
    {
    nodelist[i].weight
    =w[i];
    nodelist[i].parent
    =0;
    }
    for(i=n;i<m;i++)
    {
    Select(nodelist,i,min1,min2);
    nodelist[min1].parent
    =i;
    nodelist[min2].parent
    =i;
    nodelist[i].weight
    =nodelist[min1].weight+nodelist[min2].weight;
    nodelist[i].rightChild
    =min2;
    nodelist[i].leftChild
    =min1;
    nodelist[i].parent
    =0;
    }
    char temp [20];
    char ** code = new char * [n];
    for(i=0;i<n;i++)
    {
    int j=i;
    int index=0;
    while(j!=m-1)
    {
    if(j==nodelist[nodelist[j].parent].leftChild) temp[index++]='0';
    else temp[index++]='1';
    j
    =nodelist[j].parent;
    }
    temp[index]
    ='\0';
    code[i]
    = new char[index+1];
    strcpy(code[i],temp);
    }
    delete nodelist;
    return code;
    }

    int main()
    {
    const int size=6;
    char word[size]={'A','B','C','D','E','F'};//编码字符
    int w[size]={4,3,2,1,7,8};//权重
    char ** code;
    code
    =HuffmanCoding(w,size);
    assert(code
    !=NULL);
    for(int i=0;i<size;i++)
    {
    cout
    <<word[i]<<" is coded as "<<code[i]<<endl;
    }
    //注意二级指针的释放问题
    for(int j=0;j<size;j++)
    {
    delete []code[j];
    }
    delete []code;
    return 0;
    }

  • 相关阅读:
    完全分布式安装HBase
    HDFS常用的文件API操作
    启动HBase后遇到的一个问题
    HBase常用的数据库API操作
    HBase数据库常用操作命令
    Hive安装
    eclipse中配置hadoop开发环境
    Hadoop小程序倒排索引
    我学习设计模式的一些所想所得
    架构之路实战项目记录(二) 忘记数据库 开始抽象
  • 原文地址:https://www.cnblogs.com/coser/p/1984301.html
Copyright © 2011-2022 走看看