C/C++ 数据结构与算法【哈夫曼树】 哈夫曼树详细解析【一样平常学习,考研 ...

打印 上一主题 下一主题

主题 1034|帖子 1034|积分 3102

哈夫曼树(最优二叉树)

1)基础概念

**路径:**从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。
**结点的路径长度:**两结点间路径上的分支数。

**树的路径长度:**从树根到每一个结点的路径长度之和。记作:TL。

结点数目相同的二叉树中,完全二叉树是路径长度最短的二叉树。
**权:**将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。
**结点的带权路径长度:**从根结点到该结点之间的路径长度与该结点的权的乘积。
**树的带权路径长度:**树中全部叶子结点的带权路径长度之和。





2)构造哈夫曼树





顺序存储结构——一维结构数组

(1)界说结构


  1. typedef struct {
  2.         int weight;
  3.         int parent, lch, rch;
  4. }HTNode, * HuffmanTree;
  5. HuffmanTree H;
复制代码
(2)步骤:




  • 初始化HT [1…2n-1]:lch = rch = parent = 0;
  • 输入初始几个叶子结点:置HT[1…n]的 weight 值;
  • 进行以下n-1次归并,依次产生n-1个结点HT,i = n + 1…2n-1:

    • 在HT[1…i-1]中选两个未被选过(从parent ==0 的结点中选)的weight最小的两个结点 HT[S1] 和 HT[S2],s1、s2为两个最小结点下标;
    • 修改 HT[s1] 和 HT[s2] 的parent值:HT[s1].parent = i; HT[s2] .parent = i;
    • 修改新产生的HT

  1. HT[i].weight = HT[s1].weight + HT[s2].weight;
  2. HTli].Ich = s1;
  3. HT[i].rch = s2;
复制代码
  1. void CreatHuffmanTree(HuffmanTree& HT, int n) { //构造哈夫曼树--哈夫曼算法
  2.     if (n <= 1) return;
  3.     int m = 2 * n - 1; // 数组共2n-1个元素
  4.     HT = new HTNode[m + 1]; // 动态分配内存,0号单元未用,HT[m]表示根结点
  5.     // 初始化2n-1个元素的lch、rch、parent为0
  6.     for (int i = 1; i <= m; ++i) {
  7.         HT[i].lch = HT[i].rch = HT[i].parent = 0;
  8.     }
  9.     // 输入前n个元素的weight值
  10.     cout << "请输入" << n << "个字符的频率:" << endl;
  11.     for (int i = 1; i <= n; ++i) {
  12.         cin >> HT[i].weight;
  13.     }
  14.     // 构建哈夫曼树
  15.     for (int i = n + 1; i <= m; i++) {
  16.         int s1, s2;
  17.         Select(HT, i - 1, s1, s2);
  18.         HT[s1].parent = i;
  19.         HT[s2].parent = i;
  20.         HT[i].lch = s1;
  21.         HT[i].rch = s2;
  22.         HT[i].weight = HT[s1].weight + HT[s2].weight;
  23.     }
  24. }
复制代码
(3)总代码:

权值为整数:

  1. #include <iostream>#include <limits.h>using namespace std;// 界说哈夫曼树节点结构typedef struct {    int weight;    int parent, lch, rch;} HTNode;typedef HTNode* HuffmanTree;// 选择两个双亲域为0且权值最小的结点void Select(const HTNode* HT, int i, int& s1, int& s2) {    s1 = s2 = -1;    int min1 = INT_MAX, min2 = INT_MAX;    for (int j = 1; j <= i; ++j) {        if (HT[j].parent == 0 && HT[j].weight < min1) {            min2 = min1;            s2 = s1;            min1 = HT[j].weight;            s1 = j;        }        else if (HT[j].parent == 0 && HT[j].weight < min2) {            min2 = HT[j].weight;            s2 = j;        }    }}void CreatHuffmanTree(HuffmanTree& HT, int n) { //构造哈夫曼树--哈夫曼算法
  2.     if (n <= 1) return;
  3.     int m = 2 * n - 1; // 数组共2n-1个元素
  4.     HT = new HTNode[m + 1]; // 动态分配内存,0号单元未用,HT[m]表示根结点
  5.     // 初始化2n-1个元素的lch、rch、parent为0
  6.     for (int i = 1; i <= m; ++i) {
  7.         HT[i].lch = HT[i].rch = HT[i].parent = 0;
  8.     }
  9.     // 输入前n个元素的weight值
  10.     cout << "请输入" << n << "个字符的频率:" << endl;
  11.     for (int i = 1; i <= n; ++i) {
  12.         cin >> HT[i].weight;
  13.     }
  14.     // 构建哈夫曼树
  15.     for (int i = n + 1; i <= m; i++) {
  16.         int s1, s2;
  17.         Select(HT, i - 1, s1, s2);
  18.         HT[s1].parent = i;
  19.         HT[s2].parent = i;
  20.         HT[i].lch = s1;
  21.         HT[i].rch = s2;
  22.         HT[i].weight = HT[s1].weight + HT[s2].weight;
  23.     }
  24. }
  25. int main() {    int n;    cout << "请输入叶子节点的数目:";    cin >> n;    HuffmanTree HT;    CreatHuffmanTree(HT, n);    // 打印哈夫曼树(示例)    cout << "哈夫曼树构造完成,打印结果如下:" << endl;    for (int i = 1; i < 2 * n; ++i) {        cout << "Node " << i << ": Weight=" << HT[i].weight            << ", Parent=" << HT[i].parent            << ", Left Child=" << HT[i].lch            << ", Right Child=" << HT[i].rch << endl;    }    delete[] HT; // 开释动态分配的内存    return 0;}
复制代码
权值为浮点数

  1. #include <iostream>
  2. #include <limits.h> // 如果不再使用 INT_MAX,可以不需要这个头文件
  3. using namespace std;
  4. // 定义哈夫曼树节点结构,将 weight 改为 double 类型
  5. typedef struct {
  6.     double weight;  // 权值改为 double 类型
  7.     int parent, lch, rch;
  8. } HTNode;
  9. typedef HTNode* HuffmanTree;
  10. // 选择两个双亲域为0且权值最小的结点
  11. void Select(const HTNode* HT, int i, int& s1, int& s2) {
  12.     s1 = s2 = -1;
  13.     double min1 = DBL_MAX, min2 = DBL_MAX; // 使用 DBL_MAX 作为最大值初始化
  14.     for (int j = 1; j <= i; ++j) {
  15.         if (HT[j].parent == 0 && HT[j].weight < min1) {
  16.             min2 = min1;
  17.             s2 = s1;
  18.             min1 = HT[j].weight;
  19.             s1 = j;
  20.         }
  21.         else if (HT[j].parent == 0 && HT[j].weight < min2) {
  22.             min2 = HT[j].weight;
  23.             s2 = j;
  24.         }
  25.     }
  26. }
  27. void CreatHuffmanTree(HuffmanTree& HT, int n) { //构造哈夫曼树--哈夫曼算法
  28.     if (n <= 1) return;
  29.     int m = 2 * n - 1; // 数组共2n-1个元素
  30.     HT = new HTNode[m + 1]; // 动态分配内存,0号单元未用,HT[m]表示根结点
  31.     // 初始化2n-1个元素的lch、rch、parent为0
  32.     for (int i = 1; i <= m; ++i) {
  33.         HT[i].lch = HT[i].rch = HT[i].parent = 0;
  34.         HT[i].weight = 0.0; // 初始化 weight 为 0.0
  35.     }
  36.     // 输入前n个元素的weight值
  37.     cout << "请输入" << n << "个字符的小数频率:" << endl;
  38.     for (int i = 1; i <= n; ++i) {
  39.         cin >> HT[i].weight;
  40.     }
  41.     // 构建哈夫曼树
  42.     for (int i = n + 1; i <= m; i++) {
  43.         int s1, s2;
  44.         Select(HT, i - 1, s1, s2);
  45.         HT[s1].parent = i;
  46.         HT[s2].parent = i;
  47.         HT[i].lch = s1;
  48.         HT[i].rch = s2;
  49.         HT[i].weight = HT[s1].weight + HT[s2].weight;
  50.     }
  51. }
  52. int main() {
  53.     int n;
  54.     cout << "请输入叶子节点的数量:";
  55.     cin >> n;
  56.     HuffmanTree HT;
  57.     CreatHuffmanTree(HT, n);
  58.     // 打印哈夫曼树(示例)
  59.     cout << "哈夫曼树构造完成,打印结果如下:" << endl;
  60.     for (int i = 1; i <= 2 * n - 1; ++i) { // 注意这里应该是 2*n-1 而不是 2*n
  61.         cout << "Node " << i << ": Weight=" << HT[i].weight
  62.             << ", Parent=" << HT[i].parent
  63.             << ", Left Child=" << HT[i].lch
  64.             << ", Right Child=" << HT[i].rch << endl;
  65.     }
  66.     delete[] HT; // 释放动态分配的内存
  67.     return 0;
  68. }
复制代码
(4)运行结果:


3)哈夫曼编码

在远程通讯中,要将待传字符转换成由二进制的字符串:

若将编码设计为长度不等的二进制编码,即让待传字符串中出现次数较多的字符采用尽可能短的编码,则转换的二进制字符串便可能减少。

问题1 :什么样的前缀码能使得电文总长最短?

——哈夫曼编码
方法:
1、统计字符集中每个字符在电文中出现的均匀概率(概率越大要求编码越短)。
2、利用哈夫曼树的特点:权越大的叶子离根越近;将每个字符的概率值作为权值,构造哈夫曼树。 则概率越大的结点,路径越短。
3、在哈夫曼树的每个分支上标上0或1:


  • 结点的左分支标0,右分支桥 1。
  • 把从根到每个吐子的路径上的标号连接起来,作为该叶子代表的字符的编码。

问题2 :为什么哈夫曼编码可以或许包管是前缀编码?

因为没有一片树叶是另一片树叶的祖先,所以每个叶结点的编码就不可能是其它叶结点编码的前缀。
问题 3 :为什么哈夫曼编码可以或许包管字符编码总长最短?

因为哈夫曼树的带权路径长度最短,故字符编码的总长最短。


  • 性质1 哈夫曼编码是前缀码
  • 性质2 哈夫曼编码是最优前缀码
算法实现:

  1. // 从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
  2. void CreatHuffmanCode(const HuffmanTree& HT, HuffmanCode& HC, int n) {
  3.     HC = new char*[n + 1]; // 分配n个字符编码的头指针数组
  4.     char* cd = new char[n]; // 分配临时存放编码的动态数组空间
  5.     cd[n - 1] = '\0'; // 编码结束符
  6.     for (int i = 1; i <= n; ++i) {
  7.         int start = n - 1;
  8.         int c = i;
  9.         int f = HT[i].parent;
  10.         // 从叶子结点开始向上回溯,直到根结点
  11.         while (f != 0) {
  12.             --start;
  13.             if (HT[f].lch == c)
  14.                 cd[start] = '0'; // 结点c是f的左孩子,则生成代码0
  15.             else
  16.                 cd[start] = '1'; // 结点c是f的右孩子,则生成代码1
  17.             c = f;
  18.             f = HT[f].parent;
  19.         }
  20.         // 计算编码长度并分配适当的空间
  21.         int codeLength = n - start;
  22.         HC[i] = new char[codeLength];
  23.         strncpy(HC[i], &cd[start], codeLength);
  24.         HC[i][codeLength - 1] = '\0'; // 确保字符串以空字符终止
  25.     }
  26.     delete[] cd; // 释放临时空间
  27. }
复制代码
strncpy(HC, &cd[start], codeLength);语句在C++中确实可以用于复制字符数组,但它有一些潜在的问题和局限性。特别是当你使用strncpy时,假如目标缓冲区没有充足的空间来包罗源字符串加上制止空字符(\0),它不会自动添加制止空字符,这可能会导致后续利用出现问题。
此外,在现代C++中,更推荐使用std::string来处理字符串,因为它们更安全、更方便,并且可以克制手动管理内存的复杂性和风险。
  1. // 从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
  2. void CreatHuffmanCode(const HuffmanTree& HT, HuffmanCode& HC, int n) {
  3.     HC.resize(n + 1); // 分配n个字符编码的空间
  4.     for (int i = 1; i <= n; ++i) {
  5.         string code = "";
  6.         int c = i;
  7.         int f = HT[i].parent;
  8.         // 从叶子结点开始向上回溯,直到根结点
  9.         while (f != 0) {
  10.             if (HT[f].lch == c)
  11.                 code = '0' + code; // 结点c是f的左孩子,则生成代码0
  12.             else
  13.                 code = '1' + code; // 结点c是f的右孩子,则生成代码1
  14.             c = f;
  15.             f = HT[f].parent;
  16.         }
  17.         HC[i] = code;
  18.     }
  19. }
复制代码
总代码实现:


  1. #include <iostream>
  2. #include <cstring> // 用于 strcpy 和 strlen
  3. #include <limits>  // 用于 std::numeric_limits
  4. using namespace std;
  5. // 定义哈夫曼树节点结构
  6. typedef struct HTNode {
  7.     double weight; // 权重改为 double 类型
  8.     int parent, lch, rch;
  9. } HTNode;
  10. typedef HTNode* HuffmanTree;
  11. // 定义哈夫曼编码结构
  12. typedef char** HuffmanCode;
  13. // 选择两个双亲域为0且权值最小的结点
  14. void Select(const HTNode* HT, int i, int& s1, int& s2) {
  15.     s1 = s2 = -1;
  16.     double min1 = numeric_limits<double>::max(), min2 = numeric_limits<double>::max();
  17.     for (int j = 1; j <= i; ++j) {
  18.         if (HT[j].parent == 0 && HT[j].weight < min1) {
  19.             min2 = min1;
  20.             s2 = s1;
  21.             min1 = HT[j].weight;
  22.             s1 = j;
  23.         } else if (HT[j].parent == 0 && HT[j].weight < min2) {
  24.             min2 = HT[j].weight;
  25.             s2 = j;
  26.         }
  27.     }
  28. }
  29. // 构造哈夫曼树--哈夫曼算法
  30. void CreatHuffmanTree(HuffmanTree &HT, int n) {
  31.     if (n <= 1) return;
  32.     int m = 2 * n - 1; // 数组共2n-1个元素
  33.     HT = new HTNode[m + 1]; // 动态分配内存,0号单元未用,HT[m]表示根结点
  34.     // 初始化2n-1个元素的lch、rch、parent为0
  35.     for (int i = 1; i <= m; ++i) {
  36.         HT[i].lch = HT[i].rch = HT[i].parent = 0;
  37.         HT[i].weight = 0.0; // 初始化权重为 0.0
  38.     }
  39.     // 输入前n个元素的weight值
  40.     cout << "请输入" << n << "个字符的频率(浮点数):" << endl;
  41.     for (int i = 1; i <= n; ++i) {
  42.         cin >> HT[i].weight;
  43.     }
  44.     // 构建哈夫曼树
  45.     for (int i = n + 1; i <= m; i++) {
  46.         int s1, s2;
  47.         Select(HT, i - 1, s1, s2);
  48.         HT[s1].parent = i;
  49.         HT[s2].parent = i;
  50.         HT[i].lch = s1;
  51.         HT[i].rch = s2;
  52.         HT[i].weight = HT[s1].weight + HT[s2].weight;
  53.     }
  54. }
  55. // 从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
  56. void CreatHuffmanCode(HuffmanTree HT, HuffmanCode& HC, int n) {
  57.     HC = new char*[n + 1]; // 分配n个字符编码的头指针数组
  58.     char* cd = new char[n]; // 分配临时存放编码的动态数组空间
  59.     cd[n - 1] = '\0'; // 编码结束符
  60.     for (int i = 1; i <= n; ++i) {
  61.         int start = n - 1;
  62.         int c = i;
  63.         int f = HT[i].parent;
  64.         // 从叶子结点开始向上回溯,直到根结点
  65.         while (f != 0) {
  66.             --start;
  67.             if (HT[f].lch == c)
  68.                 cd[start] = '0'; // 结点c是f的左孩子,则生成代码0
  69.             else
  70.                 cd[start] = '1'; // 结点c是f的右孩子,则生成代码1
  71.             c = f;
  72.             f = HT[f].parent;
  73.         }
  74.         // 计算编码长度并分配适当的空间
  75.         int codeLength = n - start;
  76.         HC[i] = new char[codeLength];
  77.         strncpy(HC[i], &cd[start], codeLength);
  78.         HC[i][codeLength - 1] = '\0'; // 确保字符串以空字符终止
  79.     }
  80.     delete[] cd; // 释放临时空间
  81. }
  82. // 测试函数
  83. int main() {
  84.     int n;
  85.     cout << "请输入叶子节点的数量:";
  86.     cin >> n;
  87.     HuffmanTree HT;
  88.     CreatHuffmanTree(HT, n);
  89.     HuffmanCode HC;
  90.     CreatHuffmanCode(HT, HC, n);
  91.     // 打印哈夫曼编码
  92.     cout << "哈夫曼编码如下:" << endl;
  93.     for (int i = 1; i <= n; ++i) {
  94.         cout << "Character " << i << ": " << HC[i] << endl;
  95.     }
  96.     // 清理资源
  97.     for (int i = 1; i <= n; ++i) {
  98.         delete[] HC[i];
  99.     }
  100.     delete[] HC;
  101.     delete[] HT;
  102.     return 0;
  103. }
复制代码
改进后的代码:
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <limits>
  5. using namespace std;
  6. // 定义哈夫曼树节点结构
  7. typedef struct HTNode {
  8.     double weight; // 权重改为 double 类型
  9.     int parent, lch, rch;
  10. } HTNode;
  11. typedef HTNode* HuffmanTree;
  12. // 选择两个双亲域为0且权值最小的结点
  13. void Select(const vector<HTNode>& HT, int i, int& s1, int& s2) {
  14.     s1 = s2 = -1;
  15.     double min1 = numeric_limits<double>::max(), min2 = numeric_limits<double>::max();
  16.     for (int j = 1; j <= i; ++j) {
  17.         if (HT[j].parent == 0 && HT[j].weight < min1) {
  18.             min2 = min1;
  19.             s2 = s1;
  20.             min1 = HT[j].weight;
  21.             s1 = j;
  22.         } else if (HT[j].parent == 0 && HT[j].weight < min2) {
  23.             min2 = HT[j].weight;
  24.             s2 = j;
  25.         }
  26.     }
  27. }
  28. // 构造哈夫曼树--哈夫曼算法
  29. void CreatHuffmanTree(vector<HTNode>& HT, int n) {
  30.     if (n <= 1) return;
  31.     int m = 2 * n - 1; // 数组共2n-1个元素
  32.     // 初始化2n-1个元素的lch、rch、parent为0,权重为0.0
  33.     HT.resize(m + 1);
  34.     for (int i = 1; i <= m; ++i) {
  35.         HT[i] = {0.0, 0, 0, 0};
  36.     }
  37.     // 输入前n个元素的weight值
  38.     cout << "请输入" << n << "个字符的频率(浮点数):" << endl;
  39.     for (int i = 1; i <= n; ++i) {
  40.         cin >> HT[i].weight;
  41.     }
  42.     // 构建哈夫曼树
  43.     for (int i = n + 1; i <= m; i++) {
  44.         int s1, s2;
  45.         Select(HT, i - 1, s1, s2);
  46.         HT[s1].parent = i;
  47.         HT[s2].parent = i;
  48.         HT[i].lch = s1;
  49.         HT[i].rch = s2;
  50.         HT[i].weight = HT[s1].weight + HT[s2].weight;
  51.     }
  52. }
  53. // 从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
  54. void CreatHuffmanCode(const vector<HTNode>& HT, vector<string>& HC, int n) {
  55.     HC.resize(n + 1); // 分配n个字符编码的空间
  56.     for (int i = 1; i <= n; ++i) {
  57.         string code = "";
  58.         int c = i;
  59.         int f = HT[i].parent;
  60.         // 从叶子结点开始向上回溯,直到根结点
  61.         while (f != 0) {
  62.             if (HT[f].lch == c)
  63.                 code = '0' + code; // 结点c是f的左孩子,则生成代码0
  64.             else
  65.                 code = '1' + code; // 结点c是f的右孩子,则生成代码1
  66.             c = f;
  67.             f = HT[f].parent;
  68.         }
  69.         HC[i] = code;
  70.     }
  71. }
  72. // 测试函数
  73. int main() {
  74.     int n;
  75.     cout << "请输入叶子节点的数量:";
  76.     cin >> n;
  77.     vector<HTNode> HT;
  78.     CreatHuffmanTree(HT, n);
  79.     vector<string> HC;
  80.     CreatHuffmanCode(HT, HC, n);
  81.     // 打印哈夫曼编码
  82.     cout << "哈夫曼编码如下:" << endl;
  83.     for (int i = 1; i <= n; ++i) {
  84.         cout << "Character " << i << ": " << HC[i] << endl;
  85.     }
  86.     return 0;
  87. }
复制代码
改进后:
  1. #include <iostream>
  2. #include <cstring> // 用于 strcpy 和 strlen
  3. #include <limits>  // 用于 std::numeric_limits
  4. using namespace std;
  5. // 定义哈夫曼树节点结构
  6. typedef struct HTNode {
  7.     double weight; // 权重改为 double 类型
  8.     int parent, lch, rch;
  9. } HTNode;
  10. typedef HTNode* HuffmanTree;
  11. // 定义哈夫曼编码结构
  12. typedef char** HuffmanCode;
  13. // 选择两个双亲域为0且权值最小的结点
  14. void Select(const HTNode* HT, int i, int& s1, int& s2) {
  15.     s1 = s2 = -1;
  16.     double min1 = numeric_limits<double>::max(), min2 = numeric_limits<double>::max();
  17.     for (int j = 1; j <= i; ++j) {
  18.         if (HT[j].parent == 0 && HT[j].weight < min1) {
  19.             min2 = min1;
  20.             s2 = s1;
  21.             min1 = HT[j].weight;
  22.             s1 = j;
  23.         } else if (HT[j].parent == 0 && HT[j].weight < min2) {
  24.             min2 = HT[j].weight;
  25.             s2 = j;
  26.         }
  27.     }
  28. }
  29. // 构造哈夫曼树--哈夫曼算法
  30. void CreatHuffmanTree(HuffmanTree &HT, int n) {
  31.     if (n <= 1) return;
  32.     int m = 2 * n - 1; // 数组共2n-1个元素
  33.     HT = new HTNode[m + 1]; // 动态分配内存,0号单元未用,HT[m]表示根结点
  34.     // 初始化2n-1个元素的lch、rch、parent为0
  35.     for (int i = 1; i <= m; ++i) {
  36.         HT[i].lch = HT[i].rch = HT[i].parent = 0;
  37.         HT[i].weight = 0.0; // 初始化权重为 0.0
  38.     }
  39.     // 输入前n个元素的weight值
  40.     cout << "请输入" << n << "个字符的频率):" << endl;
  41.     for (int i = 1; i <= n; ++i) {
  42.         cin >> HT[i].weight;
  43.     }
  44.     // 构建哈夫曼树
  45.     for (int i = n + 1; i <= m; i++) {
  46.         int s1, s2;
  47.         Select(HT, i - 1, s1, s2);
  48.         HT[s1].parent = i;
  49.         HT[s2].parent = i;
  50.         HT[i].lch = s1;
  51.         HT[i].rch = s2;
  52.         HT[i].weight = HT[s1].weight + HT[s2].weight;
  53.     }
  54. }
  55. // 从叶子到根逆向求每个字符的哈夫曼编码,存储在编码表HC中
  56. void CreatHuffmanCode(HuffmanTree HT, HuffmanCode& HC, int n) {
  57.     HC = new char*[n + 1]; // 分配n个字符编码的头指针数组
  58.     for (int i = 1; i <= n; ++i) {
  59.         string code = ""; // 使用string来构建编码
  60.         int c = i;
  61.         int f = HT[i].parent;
  62.         // 从叶子结点开始向上回溯,直到根结点
  63.         while (f != 0) {
  64.             if (HT[f].lch == c)
  65.                 code = '0' + code; // 结点c是f的左孩子,则生成代码0
  66.             else
  67.                 code = '1' + code; // 结点c是f的右孩子,则生成代码1
  68.             c = f;
  69.             f = HT[f].parent;
  70.         }
  71.         // 将string转换为C风格字符串并分配适当的空间
  72.         HC[i] = new char[code.length() + 1];
  73.         strcpy(HC[i], code.c_str());
  74.     }
  75. }
  76. // 测试函数
  77. int main() {
  78.     int n;
  79.     cout << "请输入叶子节点的数量:";
  80.     cin >> n;
  81.     if (n <= 0) {
  82.         cerr << "叶子节点数量必须大于0." << endl;
  83.         return 1;
  84.     }
  85.     HuffmanTree HT;
  86.     CreatHuffmanTree(HT, n);
  87.     HuffmanCode HC;
  88.     CreatHuffmanCode(HT, HC, n);
  89.     // 打印哈夫曼编码
  90.     cout << "哈夫曼编码如下:" << endl;
  91.     for (int i = 1; i <= n; ++i) {
  92.         cout << "Character " << i << ": " << HC[i] << endl;
  93.     }
  94.     // 清理资源
  95.     for (int i = 1; i <= n; ++i) {
  96.         delete[] HC[i];
  97.     }
  98.     delete[] HC;
  99.     delete[] HT;
  100.     return 0;
  101. }
复制代码
运行结果:



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表