#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,"");
}