这里先把哈弗曼树创建出来,在进行编码,因为书上那个数组做的代码看得头晕
#include<iostream>
#include<stdlib.h>
#include<limits.h>
using namespace std;
typedef struct node
{
char datax;//存字母,若只用下面的data存下标可能和组合后的权值冲突,所以,下面那个就用来存权值
int data;
struct node *lchild, *rchild;
}htnode;
htnode *h, *p, *st[200];
int N, n, val[200], mina = 0, minb = 0, flag[200] = { 0 }, ha[100], top, flag_f;
void f(htnode *h, char idata)//输出idata的编码
{
if (flag_f == 1)
return;
if (h->datax!=NULL&&h->datax == idata)
{
for (int j = 0; j < top; j++)
cout << ha[j];
cout << "\r\n";
flag_f = 1;
return;
}
if (h->lchild != NULL)
{
ha[top] = 0;
top++;
f(h->lchild, idata);
top--;
}
if (h->rchild != NULL)
{
ha[top] = 1;
top++;
f(h->rchild, idata);
top--;
}
}
void putx(htnode *h)
{
if (h == NULL)
return;
cout << h->data << endl;
if (h->lchild != NULL)
putx(h->lchild);
if (h->rchild != NULL)
putx(h->rchild);
}
int main()
{
char s[100];
cin >> n;
N = n;
cin >> s;
for (int i = 0; i < n; i++)
{
cin >> val[i];
st[i] = (htnode*)malloc(sizeof(htnode));
st[i]->datax = s[i];
st[i]->data = i;
st[i]->lchild = NULL;
st[i]->rchild = NULL;
}
if (n == 1)
{
cout << "\r\n";
return 0;
}
int minnum;
while (1)
{
minnum = INT_MAX;//剩下节点最小的权值
for (int i = 0; i < n; i++)
{
if (flag[i] == 0 && val[i] < minnum)
{
minnum = val[i];
mina = i;
}
}//找出剩余节点最小权值的那个点mina
flag[mina] = 1;//标记为已用
minnum = INT_MAX;
for (int i = 0; i < n; i++)//再找一个
{
if (flag[i] == 0 && val[i] < minnum)
{
minnum = val[i];
minb = i;
}
}
if (minnum == INT_MAX)//当找不到第二个最小权值,则上面找那个mina已经是最后一个根节点了
break;
flag[minb] = 1;
st[n] = (htnode*)malloc(sizeof(htnode));//一个新节点
st[n]->datax = NULL;
val[n] = val[mina] + val[minb];
st[n]->data = val[n];
st[n]->lchild = st[mina];
st[n]->rchild = st[minb];
n++;
}
for (int i = 0; i < N; i++)
{
flag_f = 0;
top = 0;
f(st[mina], s[i]);
}
return 0;
}
再来个别处搞来的标准答案,数组做的
#include<iostream>
using namespace std;
typedef struct node1
{
char data;
double weight;
int parent;
int lchild;
int rchild;
}HTNode;
typedef struct node2
{
char cd[1000];
int start;
}HCode;
void CreateHT(HTNode ht[], int n)
{
int i, k, lnode, rnode;
double min1, min2;
for (i = 0; i<2 * n - 1; i++)
ht[i].parent = ht[i].lchild = ht[i].rchild = -1;
for (i = n; i<2 * n - 1; i++)
{
min1 = min2 = 32767;
lnode = rnode = -1;
for (k = 0; k <= i - 1; k++)
{
if (ht[k].parent == -1)
{
if (ht[k].weight<min1)
{
min2 = min1;
rnode = lnode;
min1 = ht[k].weight;
lnode = k;
}
else if (ht[k].weight<min2)
{
min2 = ht[k].weight;
rnode = k;
}
}
}
ht[k].weight = ht[lnode].weight + ht[rnode].weight;
ht[i].lchild = lnode;
ht[i].rchild = rnode;
ht[lnode].parent = ht[rnode].parent = i;
}
}
void CreateHCode(HTNode ht[], HCode hcd[], int n)
{
int i, c, j, f;
HCode hc;
for (i = 0; i<n; i++)
{
hc.start = n;
c = i;
f = ht[i].parent;
while (f != -1)
{
if (ht[f].lchild == c)
hc.cd[hc.start--] = '0';
if (ht[f].rchild == c)
hc.cd[hc.start--] = '1';
c = f;
f = ht[f].parent;
}
hc.start++;
hcd[i] = hc;
for (j = hcd[i].start; j <= n; j++)
cout << hcd[i].cd[j];
cout << "\r\n";
}
}
int main()
{
int n, i;
HTNode ht[1000];
HCode hcd[100];
cin >> n;
for (i = 0; i<n; i++)
cin >> ht[i].data;
for (i = 0; i<n; i++)
cin >> ht[i].weight;
CreateHT(ht, n);
CreateHCode(ht, hcd, n);
return 0;
}