Huffman编码树

#include<iostream>
using namespace std;
template<typename type>
class HuffNode
{
public:
    virtual int weight()=0;
    virtual bool isleaf()=0;
    virtual HuffNode*left()const=0;
    virtual HuffNode*right()const=0;
    virtual void setleft(HuffNode*)=0;
    virtual void setright(HuffNode*)=0;
};
//*************************************************//
//*************************************************//
template<typename type>
class FreqPair          //叶结点指针的内容,包括频率和字符
{
private:
    type it;    //可以为字符
    int freq;   //频率
public:
    FreqPair(const type&i,int f)
    {
        it=i;
        freq=f;
    }
    ~FreqPair(){}
    int weight(){return freq;} //返回权重
    type&val(){return it;}
};
//************************************************//
//**************************************************//
template<typename type>
class LeafNode:public HuffNode<type>    //叶结点实例
{
private:
    FreqPair<type>*it;   //结点内容是一个指针
public:
    LeafNode(const type&val,int freq)  //构造一个叶结点的方法
    {
        it=new FreqPair<type>(val,freq);
    }
    int weight(){return it->weight();}
    FreqPair<type>*val(){return it;}  //返回结点内容
    bool isleaf(){return true;}
    virtual HuffNode<type>*left()const{return NULL;}  //不需要实现的函数设为虚
    virtual HuffNode<type>*right()const{return NULL;}
    virtual void setleft(HuffNode<type>*){}
    virtual void setright(HuffNode<type>*){}
};
//************************************************//
//***********************************************//
template<typename type>
class IntlNode:public HuffNode<type>  //内部结点实例
{
private:
    HuffNode<type>*lc;  //左右指针
    HuffNode<type>*rc;
    int wgt;  //权重
public:
    IntlNode(HuffNode<type>*l,HuffNode<type>*r) //构造方法
    {
        wgt=l->weight()+r->weight();
        lc=l;
        rc=r;
    }
    int weight(){return wgt;}
    bool isleaf(){return false;}
    HuffNode<type>*left()const{return lc;}
    HuffNode<type>*right()const{return rc;}
    void setleft(HuffNode<type>*b){lc=(HuffNode<type>*)b;}
    void setright(HuffNode<type>*b){rc=(HuffNode<type>*)b;}
};
//****************************************************//
//*****************************************************//
template<typename type>
class HuffTree       //huff树,包含一个指向根结点的指针
{
private:
    HuffNode<type>*root; //根结点指针
public:
    HuffTree(type&val,int freq) //用于叶结点构造只有一个结点的huff树
    {
        root=new LeafNode<type>(val,freq);
    }
    HuffTree(HuffTree<type>*l,HuffTree<type>*r)  //将两棵树接起来
    {
        root=new IntlNode<type>(l->theroot(),r->theroot());
    }
    ~HuffTree(){}
    HuffNode<type>*theroot(){return root;} //返回树的根结点
    int weight(){return root->weight();}
};
//****************************************************//
//*****************************************************//
template<typename type>
class HHcompare        //用于比较两棵树的根结点权重
{
public:
    static bool lt(HuffTree<type>*x,HuffTree<type>*y)
    {
        return x->weight()<y->weight();
    }
    static bool eq(HuffTree<type>*x,HuffTree<type>*y)
    {
        return x->weight()==y->weight();
    }
    static bool gt(HuffTree<type>*x,HuffTree<type>*y)
    {
        return x->weight()>y->weight();
    }
};
//****************************************************//
//*****************************************************//
template<typename type>
class SLLNode
{
public:
    type elem;
    SLLNode*next;
    SLLNode(const type&e,SLLNode*nex)
    {
        elem=e;
        next=nex;
    }
    void setnext(SLLNode*nex){next=nex;}
};
//****************************************************//
//*****************************************************//
template<typename type1,typename type2>
class SLL     //一个有序的链表 每个结点储存的是树根
{
private:
    SLLNode<type1>*start;  //链表头部
    int Size;  //大小
public:
    SLL(){start=NULL;Size=0;}
    ~SLL(){}
    int size(){return Size;}
    SLLNode<type1>*inserthelp(SLLNode<type1>*sstart,type1 it) //辅助插入函数,插入元素后排好序
    {
        if(sstart!=NULL&&type2::lt(sstart->elem,it))
            sstart->setnext(inserthelp(sstart->next,it));
        else
        {
            SLLNode<type1>*temp=new SLLNode<type1>(it,sstart);
            sstart=temp;
        }
        return sstart;
    }
    void insert(type1 it) //调用上面的函数进行插入
    {
        start=inserthelp(start,it);
        Size++;
    }
    void remove(type1&it) //移除链表头部,即最小的树根
    {
        if(0==Size)return;
        it=start->elem;
        SLLNode<type1>*temp=start;
        start=start->next;
        delete temp;
        Size--;
    }

};
//****************************************************//
//*****************************************************//
template<typename type>
HuffTree<type>*buildHuff(SLL<HuffTree<type>*,HHcompare<type> >*f1)
{               //构建huff树,返回最终的树根
    HuffTree<type>*t1,*t2,*t3;
    while(f1->size()>1)
    {
        f1->remove(t1);
        f1->remove(t2);
        t3=new HuffTree<type>(t1,t2);
        f1->insert(t3);
        delete t1;
        delete t2;
    }
    return t3;
}
//****************************************************//
//*****************************************************//
template<typename type>
void print(HuffNode<type>*root,string s) //对每个元素打印huff编码
{
    if(!root->isleaf())
    {
        string ls=s+'0';
        print(root->left(),ls);
        string rs=s+'1';
        print(root->right(),rs);
    }
    else
    {
        LeafNode<type>*r=(LeafNode<type>*)root;
        cout<<r->val()->val()<<" code:"<<s;
        cout<<endl;
    }
}
int main()
{
    int  a[8]={2,7,24,32,37,42,42,120};
    char b[8]={'Z','K','F','C','U','D','L','E'};  //字符对应的权值在a中
    SLL<HuffTree<char>*,HHcompare<char> >*f1=new SLL<HuffTree<char>*,HHcompare<char> >;//f1指针
    for(int i=0;i<8;i++) //构建叶结点,插入f1
    {
        HuffTree<char>*t=new HuffTree<char>(b[i],a[i]);
        f1->insert(t);
    }
    HuffNode<char>*root=buildHuff(f1)->theroot(); //取得编码好的树根
    print(root,"");
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值