数据结构,顺序哈夫曼树。

最近学习树,相关实验代码感觉可以优化,希望指正。

实验要求:

  1. 一个单位有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);//自己写的倒置函数
    }	
}

运行截图:(部门编号在构造时自动递增)

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值