哈夫曼树与哈夫曼编码

哈弗曼树与哈夫曼编码

哈弗曼树
一、概念
  • WPL:设二叉树有n个叶子结点,每个叶子结点带有权值Wk,Lk是根结点到该叶子结点的长度,则叶结点带权路径长度之就位WPL。

  • WPL最小的树即为最优二叉树或者哈弗曼树

  • 这里有五个叶结点,权值为1、2、3、4、5,WPL最小的即为哈弗曼树,如右三

在这里插入图片描述

二、哈弗曼树类
```C++
//哈弗曼树结点类
template <class T> class HuffmanTreeNode{
    T weight;
    HuffmanTreeNode<T>* left;
    HuffmanTreeNode<T>* right;
    HuffmanTreeNode<T>* parent;
    HuffmanTreeNode{
        left=NULL; 
        right=NULL;
    }
    ~HuffmanTreeNode(){}
}

//哈夫曼树类

template <class T> class HuffmanTree {
private:
 HuffmanTreeNode<T>* root;//Huffman树的树根

void MergeTree(HuffmanTreeNode<T> &ht1,
HuffmanTreeNode<T> &ht2, HuffmanTreeNode<T>* parent);//把ht1和ht2两个树叶合成一个parent几点的两个儿子
public:
//构造Huffman树,weight是存储权值的数组,n是数组长度
 HuffmanTree(T weight[],int n)virtual ~HuffmanTree(){DeleteTree(root);}//析构函数
三、哈弗曼树的构造
  • 按权值(如频率或者权重)将字符排成一列,可以理解为将权值排成一个最小堆
  • 拿走最小堆中权值最小的两个字符
  • 将这两个字符即为哈弗曼树的树叶(如上图右三中1和2),将这两个树叶标位一个结点parent的两个儿子,结点parent的权值即为两个儿子权值的和。
  • 将parent结点放回最小堆,再从中取出两个权值最小的字符,重复上述步骤,直到只有最后一个字符
```C++
template<class T>
HuffmanTree<T>::HuffmanTree(T weight[],int n){
    MinHeap<HuffmanTreeNode<T>> heap;
    HuffmanTreeNode<T>* parent,&leftchild,&rightchild;
    HUffmanTreeNode<T>*  NodeList=new HuffmanTreeNode<T>[n];//理解为建立一个数组(哈弗曼树结点类型),该数组元素p存放每个权值和左右儿子和父代,以便向堆中插入p
    for(int i=0;i<n;i++){
        NodeList[i].element=weight[i];
        NodeList[i].parent=NULL;
        NodeList[i].left=NodeList[i].right=NULL;
        heap.Insert(NodeList[i]);//将NodeList类型数据入堆heap中,见前面堆的成员函数Insert()
    }//所有元素都按照权值放在堆中
    for(i=0;i<=n-1;i++){//n-1次即可,最后一次不用执行循环
        
        firstmin=heap.RemoveMin();//从堆中找到最小值并返回
        secondmin=heap.RemoveMin();
        parent=new HuffmanTreeNode<T>;//给parent变量new一个空间
        MergeTree(firstmin,secondmin,parent);//将两个树叶合并放到parent结点中
        
        heap.Insert(*parent);
        root=parent;//最后一次执行这个的时候,parent结点就是这个哈弗曼树的根结点
    }
    delete []NodeList;//释放这个当初为了往heap中存取元素的数组(哈夫曼结点类型)
        
        
}
哈弗曼编码
  • 适用于字符频率不等,差别较大的情况

  • 将频率视为权值进行哈弗曼树的构造。哈弗曼树的叶结点的权值与字符一一对应,字符的编码即为根结点到此叶结点的路径,走左路为0,走右路为1.

  • 避免了编码的二义性,即可以无二义的解码

    例如有出现频率不等的13个字符,d0-d12,则按权值对其进行哈弗曼树的构造,

在这里插入图片描述

然后叶结点的权值与原来的字符一一对应,得到其字符编码为

在这里插入图片描述

即将使用频率较高(权值高)的字符用短码表示,如d12,使用频率低(权值低)的用长码表示,如d0.

上述译码为d12d2

率较高(权值高)的字符用短码表示,如d12,使用频率低(权值低)的用长码表示,如d0.

上述译码为d12d2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值