ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

再续哈夫曼树实现

2019-09-14 20:41:12  阅读:240  来源: 互联网

标签:parent 哈夫曼 weight 再续 HuffNode 实现 int 节点


今天看了趣学算法中的有关哈夫曼树的一个问题,就蛮有兴致再写一次哈夫曼树,但这个算法的实现和我之前的哈夫曼的实现方法略有不同。 声明一下,这个实现我是采纳书上的,觉得还不错,就写了。



回顾

这个问题是这样描述的:
在远距离的信息通信过程和大容量数据存储方面运用比较广泛的数据压缩就是采用哈夫曼编码进行的。如果让我们尝试一次,哈夫曼树应该如何实现呢?
回忆一下:哈夫曼树的几个性质,我们要知道,哈夫曼树没有度为一的结点,而且N个叶子结点的哈夫曼树具有 2 * N - 1个结点 。然后呢,利用类似二叉树的分为左右两个孩子节点起关系连接作用。最后呢,我们所求得到的编码要是从叶子节点到根节点路径。了解这一些,我们就开始吧。



实现过程

我们采用的struct的存储方式,其中struct的结构体内容有

int lchild;//左孩子
int rchild;//右孩子
double weight;//权值
char value;//该节点所代表的字符

然后呢,与之前的不一样的地方来了,我们将每个叶子节点到
根节点的路径都分别用数组存起来,而不是直接建立二叉树然后遍历求权重,就如同

直接利用数字 0 和 1来区分该节点的左右孩子;
首先固定数组的最大长度,例如:bit[Maxsize],将 Maxsize 赋值为至少为 2 * N - 1;
然后呢就会这样:0 1 0 1 1 0 1表示哈夫曼编码;我觉得这样实现,比我以前的实现方法好一点,
文末附上我之前的实现方法的链接。

现在就是代码实现c++(这是原书上的)

#include<iostream>  
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
#define Maxbit 100
#define Maxvalue 1000000
#define Maxleaf 30
#define Maxnode Maxleaf * 2 - 1
typedef struct{ //节点结构体 
    double weight;
    int parent;
    int lchild;
    int rchild;
    char value;
}HnodeType;
HnodeType HuffNode[Maxnode]; //节点结构体 
typedef struct{
    int bit[Maxbit];//结点的编码 
    int start;//开始下标 
}HcodeType;
HcodeType Huffcode[Maxleaf];//编码结构体数组 
void HuffmanTree(HnodeType HuffNode[Maxnode],int n)
{
    int i,j,x1,x2;
    double m1,m2;
    for(i = 0;i < 2* n - 1;i++)
    {
        HuffNode[i].weight = 0;
        HuffNode[i].lchild = -1;
        HuffNode[i].rchild = -1;
        HuffNode[i].parent = -1;            
    }        
    for(i = 0;i <= n - 1;i++)
    {
        cout<<"Please input value and weight of leaf node "<<i + 1<<endl;
        cin>>HuffNode[i].value>>HuffNode[i].weight; 
    }
    for(i = 0; i < n - 1;i++)
    {
        m1 = m2 = Maxvalue;//无父节点且权值最小的两个节点 
        x1 = x2 = -1;
        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;    
            }     
        } 
        HuffNode[x1].parent = n + i;
        HuffNode[x2].parent = n + i;
        HuffNode[n+i].weight = m1 + m2;
        HuffNode[n+i].lchild = x1;
        HuffNode[n+i].rchild = x2; 
    }
    return ;
} 
void HuffmanCode(HcodeType Huffcode[Maxleaf],int n)
{
    HcodeType cd;
    int i,j,c,p;
    for(i = 0;i <=  n - 1;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;        
        }
        for(j = cd.start + 1;j <= n - 1;j++)
            Huffcode[i].bit[j] = cd.bit[j];
        Huffcode[i].start = cd.start;                
    } 
    return ;  
}
int main()
{
    int n,i,j;
    cout<<"请输入节点个数 :"; 
    cin>>n;
    HuffmanTree(HuffNode,n);
    HuffmanCode(Huffcode,n);
    for(i = 0;i <= n - 1;i++)
    {
        cout<<HuffNode[i].value<<": Hffuman code is : ";
        for(j = Huffcode[i].start + 1;j < n ;j ++)
            cout<<Huffcode[i].bit[j];
        cout<<endl;    
    }    
    return 0;
} 

这个是稍微改动的c语言实现,没有测试

#include<stdio.h>
#define Maxsize 1000
typedef struct{ //节点结构体 
    double weight;
    int parent;
    int lchild;
    int rchild;
    char value;
}Hnode;
Hnode HuffNode[Maxsize]; //节点结构体 
typedef struct{
    int bit[Maxsize];//结点的编码 
    int start;//开始下标 
}Hcode;
Hcode Huffcode[Maxsize];//编码结构体数组 
void HuffmanTree(int n)
{
    int i,j,x1,x2;
    double m1,m2;
    for(i = 0;i < 2 * n - 1;i++) //初始化 
    {
        HuffNode[i].weight = 0;
        HuffNode[i].lchild = -1;
        HuffNode[i].rchild = -1;
        HuffNode[i].parent = -1;            
    }     
    for(i = 0;i <= n - 1;i++)
    {
        printf("Please input value and weight of leaf node %d\n",i + 1);
        scanf("%c %lf\n",&HuffNode[i].value,&HuffNode[i].weight);
    }
    for(i = 0;i < n - 1;i++)
    {
        m1 = Maxsize;
        m2 = Maxsize;
        x1 = -1;
        x2 = -1;
        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;    
            }     
        } 
        HuffNode[x1].parent = n + i;//合并两个节点 
        HuffNode[x2].parent = n + i;
        HuffNode[n+i].weight = m1 + m2;
        HuffNode[n+i].lchild = x1;
        HuffNode[n+i].rchild = x2;    
    } 
    return ;
} 
void HuffmanCode(int n)
{
    int i,j,k;
    Hcode temp;
    for(i = 0;i <= n - 1;i++)
    {
        temp.start = n - 1;
        j = i;
        k = HuffNode[j].parent;
        while(k != -1)
        {
            if(HuffNode[k].lchild == j)
                temp.bit[temp.start] = 0;
            else
                temp.bit[temp.start] = 1;
            temp.start--;
            j = k;
            k = HuffNode[j].parent;   
        }
        for(j = temp.start + 1;j <= n - 1;j++)
        {
            Huffcode[i].bit[j] = temp.bit[j];//传给编码结构体   
        } 
        Huffcode[i].start = temp.start;//开始位置 
    }
    return ;    
} 
int main()
{
    int n,i,j;
    printf("请输入节点个数 :"); 
    scanf("%d",&n);
    HuffmanTree(n);//树的编码 
    HuffmanCode(n);//计算存储路径 
    for(i = 0;i <= n - 1;i++)
    {
        printf("%c : Hffuman code is :",HuffNode[i].value);
        for(j = Huffcode[i].start + 1;j < n ;j ++) //输出路径 
            printf("%d",Huffcode[i].bit[j]);
        printf("\n");    
    }    
    return 0;
} 

哈夫曼树讲解(二叉树)

标签:parent,哈夫曼,weight,再续,HuffNode,实现,int,节点
来源: https://blog.csdn.net/qq_44116998/article/details/100833404

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有