thinking:找到2个最小值的点,将其的值加起来成一个新结点的值,然后这个新结点是这两个结点的父节点,然后再在这些结点(父结点)中选择2个接着连成一个父结点,依次循环就可以构造出一个哈夫曼树了。
the reason of failure:1、(AA&&BB||CC)与(AA&&(BB||CC))意义是不一样的。
2、得写一个walked来记录哪个结点已经被选择过了而不能再次被选择。
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
struct ttt{
int left,right,parent,weight;
}tree[1005];
struct tt2{
int num,weight;
};
int clock;
bool walked[1005];
int creat(int n){
int i,j;
tt2 min1,min2;
int x;
for(i=1;i<n;i++){
memset(walked,0,sizeof(walked));
min1.weight=9999;
min2.weight=9999;
for(j=1;j<=n;j++){
x=j;
while(tree[x].parent!=-1){
x=tree[x].parent;
}
//cout << tree[x].weight << "GG" << endl;
if(walked[x]==0&&(min1.weight>tree[x].weight||min2.weight>tree[x].weight)){
// cout << min1.weight << "\t" << min2.weight << endl;
walked[x]=1;
if(min1.weight>min2.weight){
// cout << "min1" << endl;
min1.num=x;
min1.weight=tree[x].weight;
}else{
// cout << "min2" << endl;
min2.num=x;
min2.weight=tree[x].weight;
}
}
}
clock++;
//cout << min1.num <<"\t" << min2.num << endl;
tree[min1.num].parent=clock;
tree[min2.num].parent=clock;
tree[clock].weight=tree[min1.num].weight+tree[min2.num].weight;
if(tree[min1.num].weight>tree[min1.num].weight){
tree[clock].right=min1.num;
tree[clock].left=min2.num;
}else{
tree[clock].right=min2.num;
tree[clock].left=min1.num;
}
tree[clock].parent=-1;
//cout << tree[clock].weight <<"\t" << min1.num<< "\t" << min2.num << endl;
}
}
int fun(int x,int t){
if(tree[x].parent!=-1){
fun(tree[x].parent,++t);
}else{
return t;
}
}
void init(int n){
int i;
for(i=1;i<=n;i++){
tree[i].parent=-1;
tree[i].left=0;
tree[i].right=0;
}
}
int main(){
freopen("in.txt","r",stdin);
memset(tree,0,sizeof(tree));
int i,j,k,l,n,m,t1,t2,t3,f1,f2;
cin >> n;
clock=n;
for(i=1;i<=n;i++)
cin >> tree[i].weight;
init(n);
creat(n);
//print(n+n-1);
int sum=0;
for(i=1;i<=n;i++){
int gg=fun(i,1);
sum+=gg*tree[i].weight;
}
cout << sum << endl;
return 0;
}