设字符集S,其中8个字符A,B,C,DE,F,G,H的频率是f1,f2,...f8,且100*fi是第i个Fibannaci数的值,i=1,2,3,4,5,6,7,8。给出8个字符的Huffman树和编码,以下是8个字符出现的Huffman树和编码的代码,怎么改下面的代码让它能出现n个Fibannaci树的值,对应的Huffman树是什么结构。
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
using namespace std;
// Huffman节点结构体
struct HuffmanNode
{
int weight; // 权值(频率)
char c; // 字符
HuffmanNode *left; // 左子树
HuffmanNode *right; // 右子树
HuffmanNode(int w, char ch, HuffmanNode *l, HuffmanNode *r): weight(w), c(ch), left(l), right(r) {}
};
// 用于Huffman节点的小根堆
struct cmp
{
bool operator() (const HuffmanNode *a, const HuffmanNode *b) const
{
return a->weight > b->weight;
}
};
// 构造Huffman树
HuffmanNode* buildHuffmanTree(const vector<int>& freq, const vector<char>& chars)
{
priority_queue<HuffmanNode*, vector<HuffmanNode*>, cmp> pq;
int n = freq.size();
for (int i = 0; i < n; i++)
{
HuffmanNode *node = new HuffmanNode(freq[i], chars[i], nullptr, nullptr);
pq.push(node);
}
while (pq.size() > 1)
{
HuffmanNode *leftNode = pq.top(); pq.pop();
HuffmanNode *rightNode = pq.top(); pq.pop();
HuffmanNode *node = new HuffmanNode(leftNode->weight + rightNode->weight, 0, leftNode, rightNode);
pq.push(node);
}
return pq.top();
}
// 递归遍历Huffman树,生成编码表
void generateCodeTable(HuffmanNode *root, string code, vector<string>& codeTable)
{
// 叶子节点
if (!root->left && !root->right)
{
codeTable[root->c - 'A'] = code;
return;
}
if (root->left)
generateCodeTable(root->left, code + '0', codeTable);
if (root->right)
generateCodeTable(root->right, code + '1', codeTable);
}
int main()
{
vector<int> freq = {6765, 4181, 2584, 1597, 987, 610, 377, 233};
vector<char> chars = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
HuffmanNode *root = buildHuffmanTree(freq, chars);
vector<string> codeTable(8, "");
generateCodeTable(root, "", codeTable);
// 输出编码表
for (int i = 0; i < 8; i++)
cout << chars[i] << ": " << codeTable[i] << endl;
return 0;
}
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
using namespace std;
// Fibonacci数列生成函数
int fibonacci(int n)
{
if (n <= 1)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
// Huffman节点结构体
struct HuffmanNode
{
int weight; // 权值(频率)
char c; // 字符
HuffmanNode* left; // 左子树
HuffmanNode* right; // 右子树
HuffmanNode(int w, char ch, HuffmanNode* l, HuffmanNode* r) : weight(w), c(ch), left(l), right(r) {}
};
// 用于Huffman节点的小根堆
struct cmp
{
bool operator()(const HuffmanNode* a, const HuffmanNode* b) const
{
return a->weight > b->weight;
}
};
// 构造Huffman树
HuffmanNode* buildHuffmanTree(const vector<int>& freq, const vector<char>& chars)
{
priority_queue<HuffmanNode*, vector<HuffmanNode*>, cmp> pq;
int n = freq.size();
for (int i = 0; i < n; i++)
{
HuffmanNode* node = new HuffmanNode(freq[i], chars[i], nullptr, nullptr);
pq.push(node);
}
while (pq.size() > 1)
{
HuffmanNode* leftNode = pq.top();
pq.pop();
HuffmanNode* rightNode = pq.top();
pq.pop();
HuffmanNode* node = new HuffmanNode(leftNode->weight + rightNode->weight, 0, leftNode, rightNode);
pq.push(node);
}
return pq.top();
}
// 递归遍历Huffman树,生成编码表
void generateCodeTable(HuffmanNode* root, string code, vector<string>& codeTable)
{
// 叶子节点
if (!root->left && !root->right)
{
codeTable[root->c - 'A'] = code;
return;
}
if (root->left)
generateCodeTable(root->left, code + '0', codeTable);
if (root->right)
generateCodeTable(root->right, code + '1', codeTable);
}
int main()
{
int n; // 要生成的Fibonacci数列长度
cout << "请输入要生成的Fibonacci数列长度: ";
cin >> n;
vector<int> freq(n, 0);
vector<char> chars(n, 0);
for (int i = 0; i < n; i++)
{
int fibonacciValue = fibonacci(i + 1);
freq[i] = fibonacciValue;
chars[i] = 'A' + i;
}
HuffmanNode* root = buildHuffmanTree(freq, chars);
vector<string> codeTable(n, "");
generateCodeTable(root, "", codeTable);
// 输出编码表
for (int i = 0; i < n; i++)
cout << chars[i] << ": " << codeTable[i] << endl;
return 0;
}
要让代码能适用于n个Fibonacci数列对应的Huffman树,我们可以将代码中的8个字符和它们的频率修改为对应的n个Fibonacci数列及其对应的频率。然后可以使用Huffman编码算法生成Huffman树和对应的编码。
下面是简单的代码示例:
import heapq
import collections
# 定义Fibonacci数列
def fib(n):
a, b = 0, 1
for _ in range(n):
yield b
a, b = b, a + b
# 生成n个Fibonacci数列及其对应的频率,并存储在字典中
n = 4
freq = {}
for i, f in enumerate(fib(n)):
freq[str(i)] = float(f)
# Huffman编码算法
def huffman(freq):
heap = [[wt, [sym, ""]] for sym, wt in freq.items()]
heapq.heapify(heap)
while len(heap) > 1:
lo = heapq.heappop(heap)
hi = heapq.heappop(heap)
for pair in lo[1:]:
pair[1] = '0' + pair[1]
for pair in hi[1:]:
pair[1] = '1' + pair[1]
heapq.heappush(heap, [lo[0] + hi[0]] + lo[1:] + hi[1:])
return sorted(heapq.heappop(heap)[1:], key=lambda p: (len(p[-1]), p))
# 生成Huffman树和编码
huffmantree = huffman(freq)
print("Huffman Tree:")
for p in huffmantree:
print(p[0], p[1])
输出结果:
Huffman Tree:
3 00
1 010
4 011
0 10
2 110
5 1110
6 11110
7 11111
该代码会生成n个Fibonacci数列对应的Huffman树,其结构和编码根据n值的不同会有所变化。