c++实现哈夫曼树编码

来源:互联网 发布:淘宝网男手提包 编辑:程序博客网 时间:2024/06/05 19:46

哈夫曼编码

哈夫曼编码定义:

它是由n个带权叶子结点构成的所有二叉树中带权路径长度最短的二叉树。因为这种树最早由哈夫曼(Huffman)研究,所以称为哈夫曼树,又叫最优二叉树。    

哈夫曼编码原理:百度百科

           哈夫曼树是一种树形结构,用哈夫曼树的方法解编程题的算法就叫做哈夫曼算法。树并不是指植物,而是一种数据结构,因为其存放方式颇有点象一棵树有树叉因而称为树。 最简哈夫曼树是由德国数学家冯.哈夫曼 发现的,此树的特点就是引出的路程最短。概念理解:(1)路径 从树中一个节点到另一个节点之间的分支构成这两个节点之间的路径。(2)路径长度 路径上的分支数目称作路径长度。编码原理详解相关博文:相关博文

实现步骤:

(1)初始化: 根据给定的n个权值{w1,w2,…wn}构成n棵二叉树的集合F={T1,T2,..,Tn},其中每棵二叉树Ti中只有一个带权wi的根结点,左右子树均空。
(2)找最小树:在F中选择两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,且至新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
(3)删除与加入:在F中删除这两棵树,并将新的二叉树加入F中。
(4) 判断:重复前两步(2和3),直到F中只含有一棵树为止。该树即为哈夫曼树

C++实现源码:

#include<iostream>#include<iomanip>#include <functional>#include<queue>using namespace std;#define SIZE 8typedef unsigned int WeightType;#define NIL -1struct HaffNode//哈夫曼树节点{    WeightType weight;//权值    int        parent;    int        leftchild;    int        rightchild;};typedef HaffNode HaffManTree[SIZE*2];struct HaffCode{    char ch;    char code[SIZE+1];};typedef HaffCode HaffCoding[SIZE+1];//初始化哈夫曼树void Init_HaffTree(HaffManTree hft){    for(int i = 0;i<SIZE*2;++i)    {        hft[i].weight = NIL;        hft[i].parent = 0;        hft[i].leftchild = 0;        hft[i].rightchild = 0;    }    for(int i =1;i<=SIZE;++i)    {        cin>>hft[i].weight;    }}bool Get2Min(HaffManTree hft,int n,int& index1,int& index2){    int i = 1;    while(i<n && hft[i].parent != 0) ++i;    if(i == n) return false;    for(int j = i+1;j<n;++j)    {        if(hft[j].parent == 0 && hft[i].weight > hft[j].weight)        {            i = j;        }    }    index1 = i;    hft[i].parent = -1;    i = 1;    while(i<n && hft[i].parent != 0) ++i;    if(i == n) return false;    for(int j = i+1;j<n;++j)    {        if(hft[j].parent == 0 && hft[i].weight > hft[j].weight)        {            i = j;        }    }    index2 = i;    hft[i].parent = -1;    return true;}void Create_HaffTree(HaffManTree hft){    struct IndexNode    {        int index;        WeightType w;        operator WeightType()  const { return w;}    };    priority_queue<IndexNode,vector<IndexNode>,greater<IndexNode> > q2min;    for(int i = 1;i<=SIZE;++i)    {        IndexNode x ={ i,hft[i].weight};        q2min.push(x);    }    int k = SIZE+1;    while(k < SIZE*2)    {        if(q2min.empty()) break;        IndexNode m1 = q2min.top(); q2min.pop();        if(q2min.empty()) break;        IndexNode m2 = q2min.top(); q2min.pop();        hft[k].weight = hft[m1.index].weight + hft[m2.index].weight;        hft[k].leftchild = m1.index;        hft[k].rightchild = m2.index;        hft[m1.index].parent = k;        hft[m2.index].parent = k;        IndexNode x={k,hft[k].weight};        q2min.push(x);        ++k;    }}//打印哈夫曼树void Print_HaffTree(HaffManTree hft){    for(int i = 1;i<SIZE*2; ++i)    {        cout<<setw(3)<<i;        cout<<setw(4)<<hft[i].weight;        cout<<setw(4)<<hft[i].parent;        cout<<setw(4)<<hft[i].leftchild;        cout<<setw(4)<<hft[i].rightchild<<endl;    }    cout<<endl;}void Init_HaffCode(HaffCoding hc){    for(int i=0;i<SIZE+1;++i)    {        hc[i].ch = '\0';        memset(hc[i].code,0,sizeof(char)*(SIZE+1));    }    for(int i = 1;i<SIZE+1;++i)    {        cin>>hc[i].ch;    }}void Print_HaffCode(HaffCoding hc){    for(int i = 1;i<SIZE+1;++i)    {        cout<<hc[i].ch<<"-> "<<hc[i].code<<endl;    }    cout<<endl;}void Create_HaffCode(HaffManTree hft,HaffCoding hc){    char code[SIZE+1];    for(int i = 1;i<=SIZE;++i)    {        int c = i;        int pa = hft[c].parent;        int k = SIZE;        code[k] = '\0';        while(pa != 0)        {            code[--k] = hft[pa].leftchild == c? '1':'0';            c = pa;            pa = hft[c].parent;        }        strcpy(hc[i].code,&code[k]);    }}void main(){    HaffManTree hft;    HaffCoding hc;    Init_HaffTree(hft);    Init_HaffCode(hc);    Create_HaffTree(hft);    Print_HaffTree(hft);    Create_HaffCode(hft,hc);    Print_HaffCode(hc);}
原创粉丝点击