哈夫曼树(不太详细的讲解,以后会更新的)

关于建树的关键点,都在下面代码的注释里了。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int inf=0x3f3f3f3f;
typedef struct
{
    char data;
    double weight;
    int parent;
    int lchild;
    int rchild;
}HTNode;

 typedef struct
 {
     char cd[101];
     int start;
 }HCode;

void CreatHT(HTNode ht[],int n0)
{
    int lnode,rnode;
    double min1,min2;
    for(int i=0;i<2*n0-1;i++)
        ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
    for(int i=n0;i<=2*n0-2;i++)//每一次大循环都是更新一个父节点
    {
        min1=min2=inf;
        lnode=rnode=-1;
        for(int k=0;k<=i-1;k++) //核心思想:一趟遍历,找出两个权值最小的点
            if(ht[k].parent==-1) //在尚未构造二叉树的点中寻找
            {
                //根据下面的算法,必有min1<=min2。
                if(ht[k].weight<min1) //如果当前点比已知最小的点还要小
                {
                    min2=min1; rnode=lnode;//更新已知的第二小的点
                    min1=ht[k].weight; lnode=k;//更新已知的最小的点
                }
                else if(ht[k].weight<min2)//如果当前点大于等于已知最小的点但是小于已知的第二小的点
                {
                    min2=ht[k].weight; rnode=k; //更新第二小的点
                }
            }
        //更新父节点
        ht[i].weight=ht[lnode].weight+ht[rnode].weight;
        ht[i].rchild=rnode;ht[i].lchild=lnode;
        ht[rnode].parent=i; ht[lnode].parent=i;
    }
}

void CreatHCode(HTNode ht[],HCode hcd[],int n0)
{
    HCode hc;
    for(int i=0;i<n0;i++)
    {
        hc.start=n0;
        int c=i;
        int f=ht[i].parent;
        while(f!=-1)
        {
            if(ht[f].lchild==c) //若当前点是父结点的左孩子,就添加0
                hc.cd[hc.start--]='0';
            else  //若当前点是父结点的右孩子,就添加1
                hc.cd[hc.start--]='1';
            c=f;
            f=ht[f].parent;
        }
        hc.start++;
        hcd[i]=hc;
    }
}


int main()
{
    //想要学习的其他点:1怎么遍历这棵树?2 怎么对它进行编码?3 怎么对编码实现译码?
    return 0;
}

关于哈夫曼编码为什么得到的一定是前缀码:

  1. 同一层上的点,由于编码的长度相等且不同,所以任意两个同一层上的点(0001,0000)相互之间肯定不可能有前缀。
  2. 不同层上的点:由于我们建树得到的要编码的对象(a,b,c,d,e,f,g)都在叶子结点,所以编码的对象后面没有连着结点,所以对于同一分枝上的来说,没有前缀 码;对于其他分枝上的来说,由于路径不同,小层上的点(短的码)也不可能成为长的码的前缀。                                                                                      
  3.     结合图看:                                                                                                                                                                                                         huffman
发布了77 篇原创文章 · 获赞 11 · 访问量 4985

猜你喜欢

转载自blog.csdn.net/qq_43346054/article/details/103631118