时间限制:1000MS 代码长度限制:10KB
提交次数:3178 通过次数:1263
题型: 编程题 语言: G++;GCC
Description
利用静态链表建立赫夫曼树,建树过程中要求左子树权值小于右子树权值,求各结点的编码。要求:叶子结点的个数n及结点值由键盘录入。本题给出程序代码,要求填空以满足测试要求. #include "stdio.h" #include "string.h" #include using namespace std; typedef struct { unsigned int weight; unsigned int parent,lchild,rchild; } HTNode,*HuffmanTree; typedef char **HuffmanCode; void select(HuffmanTree &HT, int n, int &s1, int &s2) {//在HT[1..n]中选择parent为0且weight最小的两个结点, 其序号分别为s1(最小)和s2(次小)。 __________________________ } void createHuffmanTree(HuffmanTree &HT, int n) { //构造哈夫曼树HT int i, m, s1, s2; if (n<=1) return; m = 2 * n - 1; HT = new HTNode[m+1]; // 0号单元未用 for (i=1; i<=m; i++) { //初始化HT数组 HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0; } for (i=1; i<=n; i++) cin>>HT[i].weight; for (i=n+1; i<=m; i++) // 建哈夫曼树 { //在HT[1..i-1]中选择parent为0且weight最小的两个结点, 其序号分别为s1(最小)和s2(次小) _______________________________ } } void createHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n) {//--- 从叶子到根逆向求每个字符的哈夫曼编码 --- char *cd = new char[n]; // 分配求编码的工作空间 cd[n-1] = '\0'; // 编码结束符。 int i,c,f,start; for (i=1; i<=n; ++i) { start = n-1; c=i, f=HT[i].parent; while(f)// 从叶子到根逆向求编码 { --start; if (HT[f].lchild==c) cd[start] = '0'; else cd[start] = '1'; c=f,f=HT[f].parent; } HC[i] = new char[n-start];// 为第i个字符编码分配空间 strcpy(HC[i], &cd[start]); // 从cd复制编码(串)到HC } } int main() { int i,n; int *w; HuffmanTree HT; HuffmanCode HC; scanf("%d",&n); //权值个数 HC=new char*[n+1]; //0空间未用 createHuffmanTree(HT,n); createHuffmanCode(HT,HC,n); for (i = 1; i<=n; i++) printf("%s\n",HC[i]); //输出哈夫曼编码 }
输入格式
第一行:权值个数 第二行:输入n个权值,用空格分隔
输出格式
输出n行 每行表示各权值对应的哈夫曼编码
输入样例
8 5 29 7 8 14 23 3 11
输出样例
0001 10 1110 1111 110 01 0000 001
作者
yqm
Version:
17
//#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "string.h"
#include "iostream"
//#define scanf scanf_s
using namespace std;
typedef struct
{
unsigned int weight;
unsigned int parent, lchild, rchild;
} HTNode, * HuffmanTree;
typedef char** HuffmanCode;
void select(HuffmanTree& HT, int n, int& s1, int& s2)
{//在HT[1..n]中选择parent为0且weight最小的两个结点, 其序号分别为s1(最小)和s2(次小)。
int i,minwei=999,mins,t;
for (i = 1; i <= n; i++) {
if (!HT[i].parent&&minwei>HT[i].weight) {
minwei = HT[i].weight;
mins = i;
}
}
s1 = mins;
t = HT[s1].parent;
HT[s1].parent = 1;
minwei = 999;
for (i = 1; i <= n; i++) {
if (!HT[i].parent && minwei > HT[i].weight) {
minwei = HT[i].weight;
mins = i;
}
}
s2 = mins;
HT[s1].parent = t;
}
void createHuffmanTree(HuffmanTree& HT, int n)
{ //构造哈夫曼树HT
int i, m, s1, s2;
if (n <= 1) return;
m = 2 * n - 1;
HT = new HTNode[m + 1]; // 0号单元未用
for (i = 1; i <= m; i++) { //初始化HT数组
HT[i].parent = 0; HT[i].lchild = 0; HT[i].rchild = 0;
}
for (i = 1; i <= n; i++)
cin >> HT[i].weight;
for (i = n + 1; i <= m; i++) // 建哈夫曼树
{ //在HT[1..i-1]中选择parent为0且weight最小的两个结点, 其序号分别为s1(最小)和s2(次小)
select(HT, i-1, s1, s2);
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
}
void createHuffmanCode(HuffmanTree HT, HuffmanCode& HC, int n)
{//--- 从叶子到根逆向求每个字符的哈夫曼编码 ---
char* cd = new char[n]; // 分配求编码的工作空间
cd[n - 1] = '\0'; // 编码结束符。
int i, c, f, start;
for (i = 1; i <= n; ++i)
{
start = n - 1;
c = i, f = HT[i].parent;
while (f)// 从叶子到根逆向求编码
{
--start;
if (HT[f].lchild == c) cd[start] = '0';
else cd[start] = '1';
c = f, f = HT[f].parent;
}
HC[i] = new char[n - start];// 为第i个字符编码分配空间
strcpy(HC[i], &cd[start]); // 从cd复制编码(串)到HC
}
}
int main()
{
int i, n;
HuffmanTree HT;
HuffmanCode HC;
scanf("%d", &n); //权值个数
HC = new char* [n + 1]; //0空间未用
createHuffmanTree(HT, n);
createHuffmanCode(HT, HC, n);
for (i = 1; i <= n; i++)
printf("%s\n", HC[i]); //输出哈夫曼编码
}