函数SelectTwoMin(int upbound, HuffmanTree HT, int &s1, int &s2)是从1到upbound中找出father为0的节点赋给s1,s2,(为了保证答案唯一,请让s1的节点编号小于s2),函数HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)是构造哈夫曼树以及计算哈夫曼编码。保证输入的权重值小于1000。
函数接口定义:
void SelectTwoMin(int upbound, HuffmanTree HT, int &s1, int &s2);
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n);
其中 upbound
编号,HT
是哈夫曼树,HC
是哈夫曼编码,w
是权值,n
是叶子节点个数。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int weight;
int parent;
int lchild;
int rchild;
} HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
void SelectTwoMin(int upbound, HuffmanTree HT, int &s1, int &s2);
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n);
int main() {
HuffmanTree ht;
HuffmanCode hc;
int n;
scanf("%d", &n);
int *w = (int *) malloc (n * sizeof(int));
for(int i = 0; i < n; ++ i)
scanf("%d", &w[i]);
HuffmanCoding(ht, hc, w, n);
for (int i = 1; i <= 2 * n - 1; ++ i) {
printf("%d %d %d %d\n",
ht[i].weight, ht[i].parent, ht[i].lchild, ht[i].rchild);
}
for (int i = 1; i <= n; ++ i)
printf("%s\n", hc[i]);
free(w);
free(ht);
for (int i = 1; i <= n; ++ i)
free(hc[i]);
return 0;
}
/* 你的代码将被嵌在这里 */
####输入格式:
第一行输入一个数n,表示叶子节点的个数,接下去输入n个整数,表示每个节点的值
####输出格式:
只要建树即可,输出已经确定了
输入样例:
4
1 2 3 4
输出样例:
1 5 0 0
2 5 0 0
3 6 0 0
4 7 0 0
3 6 1 2
6 7 3 5
10 0 4 6
110
111
10
0
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int weight;
int parent;
int lchild;
int rchild;
} HTNode, *HuffmanTree;
typedef char ** HuffmanCode;
void SelectTwoMin(int upbound, HuffmanTree HT, int &s1, int &s2);
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n);
int main() {
HuffmanTree ht;
HuffmanCode hc;
int n;
scanf("%d", &n);
int *w = (int *) malloc (n * sizeof(int));
for(int i = 0; i < n; ++ i)
scanf("%d", &w[i]);
HuffmanCoding(ht, hc, w, n);
for (int i = 1; i <= 2 * n - 1; ++ i) {
printf("%d %d %d %d\n",
ht[i].weight, ht[i].parent, ht[i].lchild, ht[i].rchild);
}
for (int i = 1; i <= n; ++ i)
printf("%s\n", hc[i]);
free(w);
free(ht);
for (int i = 1; i <= n; ++ i)
free(hc[i]);
return 0;
}
/* 你的代码将被嵌在这里 */
void SelectTwoMin(int upbound, HuffmanTree HT, int &s1, int &s2)
{
int min1=10000,min2=10000,num1,num2;
for(int i=1;i<=upbound;i++)
{
if(HT[i].parent==0&&HT[i].weight<min1)
{
min2=min1;
num2=num1;
min1=HT[i].weight;
num1=i;
}
else if (HT[i].parent==0&&HT[i].weight<min2)
{
min2=HT[i].weight;
num2=i;
}
s1=num1;
s2=num2;
}
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
//空间开辟
HT=(HuffmanTree)malloc(sizeof(HTNode)*(2*n-1));
HC=(char**)malloc(sizeof(char*)*(n+1));//注意这里只是开辟了(n+1)个数组指针,各个指针并没有开辟空间
for(int i=0;i<(n+1);i++)//给每个字符串开辟空间
{
HC[i]=(char*)malloc(sizeof(char)*(n+1));
memset(HC[i],0,sizeof(char)*(n+1));
}
//赋初值
for(int i=1;i<=2*n-1;i++)
{
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
if(i<=n)
HT[i].weight=w[i-1];
else
HT[i].weight=0;
}
//构建哈夫曼树
for(int i=n+1;i<=2*n-1;i++)
{
int s1=0,s2=0;
SelectTwoMin(i-1,HT,s1,s2);//找出当前最小的两个数下标
HT[i].lchild=s1;//更新
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+ HT[s2].weight;
HT[s1].parent=i;
HT[s2].parent=i;
}
for(int i=1;i<=n;i++)
{
char *a="";//从叶子开始往上找直到根节点
a=(char*)malloc(sizeof(char)*(n+1));
int k=i;
int top=n-1;
a[n]='\0';
while(HT[k].parent)
{
if(HT[HT[k].parent].lchild==k)
{
a[top--]='0';
}
else if(HT[HT[k].parent].rchild==k)
{
a[top--]='1';
}
}
strcpy(HC[k],a+top+1);//复制过去
}
}