最近学习树,相关实验代码感觉可以优化,希望指正。
实验要求:
- 一个单位有5个部门,每个部门都有一部电话,但是整个单位只有一根外线,当有电话打过来的时候,由转接员转到内线电话,已知各部门使用外线电话的频率为(次/天):5 16 9 12 19。利用哈夫曼树算法思想设计内线电话号码,使得接线员拨号次数尽可能少。要求:
(1)依据使用外线电话的频率构造二叉树;
(2)输出设计出的各部门内线电话号码。
哈夫曼树结构体定义:
typedef struct Hufftree{//定义Huffman树,结点类型和指针型。
int wight;
char data;
int p;
int lc;
int rc;
char s[20];
}*Htree,Hnode;
输入树的数据:
void newHtree(int n,Htree &h){//输入结点数据,生成树表。
int i;
int m=2*n;
int c=65;
h=new Hnode[m];
cout<<"输入权重"<<endl;
for(i=1;i<=n;i++){
cin>>h[i].wight;
h[i].data=(char)c;
newHnode(h[i]);
c++;
}
}
构造树时选择结点的函数:
void selectnode(Htree h,int &i0,int &j0,int n){//贪心算法寻找最适合合并的结点
int min=100000;
int cur;
int i;
int j;
for(i=1;i<2*n-1;i++){
if(h[i].wight==0||h[i].p!=0)
continue;
for(j=i+1;j<=2*n-1;j++){
if(h[j].wight==0||h[j].p!=0)
continue;
cur=h[i].wight+h[j].wight;
if(cur<min){
min=cur;
i0=i;
j0=j;
}
}
}
}
初始化及构造树:
void newHnode( Hnode &h){//初始化结点,将父亲和孩子结点置为空。
h.p=0;
h.lc=0;
h.rc=0;
}
void creatHtree(Htree&h,int n){//创造Huffman树,将增加的空结点的数据域置为^根结点设为#。
int m=n+1;
int m1,n1;
int i=0;
for(i=n+1;i<=2*n;i++){
h[i].data='^';
newHnode(h[i]);}
while(true){
selectnode(h,m1,n1,n);
h[m].wight=h[m1].wight+h[n1].wight;
h[m].lc=m1;
h[m].rc=n1;
h[m1].p=m;
h[n1].p=m;
m++;
if(m==2*n){
h[2*n-1].data='#';
break;}
}
}
Huffman编码:
void huffmancode(Htree h,int n){//从叶子结点开始,编码再利用 reverse()倒置。
int i,j,k,f;
for(i=1;i<=2*n-1;i++){
if(h[i].data!='^'&&h[i].data!='#'){
j=i;
k=i;
while(h[j].data!='#'){
f=h[j].p;
if(h[f].lc==j)
strcat(h[k].s,"0");
else
strcat(h[k].s,"1");
j=f;
}
}
reverse(h[k].s);//自己写的倒置函数
}
}
运行截图:(部门编号在构造时自动递增)