• 哈夫曼编码


     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 //Huffman树的节点类
     7 typedef struct Node
     8 {
     9     char value;               //结点的字符值   
    10     int weight;               //结点字符出现的频度
    11     Node *lchild, *rchild;     //结点的左右孩子
    12 }Node;
    13 
    14 //自定义排序规则,即以vector中node结点weight值升序排序
    15 bool ComNode(Node *p, Node *q)
    16 {
    17     return p->weight<q->weight;
    18 }
    19 
    20 //构造Huffman树,返回根结点指针
    21 Node* BuildHuffmanTree(vector<Node*> vctNode)
    22 {
    23     while (vctNode.size()>1)                            //vctNode森林中树个数大于1时循环进行合并
    24     {
    25         sort(vctNode.begin(), vctNode.end(), ComNode);   //依频度高低对森林中的树进行升序排序
    26 
    27         Node *first = vctNode[0];    //取排完序后vctNode森林中频度最小的树根
    28         Node *second = vctNode[1];   //取排完序后vctNode森林中频度第二小的树根
    29         Node *merge = new Node;      //合并上面两个树
    30         merge->weight = first->weight + second->weight;
    31         merge->lchild = first;
    32         merge->rchild = second;
    33 
    34         vector<Node*>::iterator iter;
    35         iter = vctNode.erase(vctNode.begin(), vctNode.begin() + 2);    //从vctNode森林中删除上诉频度最小的两个节点first和second
    36         vctNode.push_back(merge);                                 //向vctNode森林中添加合并后的merge树
    37     }
    38     return vctNode[0];            //返回构造好的根节点
    39 }
    40 
    41 //用回溯法来打印编码
    42 void PrintHuffman(Node *node, vector<int> vctchar)
    43 {
    44     if (node->lchild == NULL && node->rchild == NULL)
    45     {//若走到叶子节点,则迭代打印vctchar中存的编码
    46         cout << node->value << ": ";
    47         for (vector<int>::iterator iter = vctchar.begin(); iter != vctchar.end(); iter++)
    48             cout << *iter;
    49         cout << endl;
    50         return;
    51     }
    52     else
    53     {
    54         vctchar.push_back(1);     //遇到左子树时给vctchar中加一个1
    55         PrintHuffman(node->lchild, vctchar);
    56         vctchar.pop_back();       //回溯,删除刚刚加进去的1
    57         vctchar.push_back(0);     //遇到左子树时给vctchar中加一个0
    58         PrintHuffman(node->rchild, vctchar);
    59         vctchar.pop_back();       //回溯,删除刚刚加进去的0
    60 
    61     }
    62 }
    63 
    64 int main()
    65 {
    66     cout << "************ Huffman编码问题 ***************" << endl;
    67     cout << "请输入要编码的字符,并以空格隔开(个数任意):" << endl;
    68     vector<Node*> vctNode;        //存放Node结点的vector容器vctNode
    69     char ch;                      //临时存放控制台输入的字符
    70     while ((ch = getchar()) != '
    ')
    71     {
    72         if (ch == ' ')continue;      //遇到空格时跳过,即没输入一个字符空一格空格
    73         Node *temp = new Node;
    74         temp->value = ch;
    75         temp->lchild = temp->rchild = NULL;
    76         vctNode.push_back(temp);  //将新的节点插入到容器vctNode中
    77     }
    78 
    79     cout << endl << "请输入每个字符对应的频度,并以空格隔开:" << endl;
    80     for (int i = 0; i<vctNode.size(); i++)
    81         cin >> vctNode[i]->weight;
    82 
    83     Node *root = BuildHuffmanTree(vctNode);   //构造Huffman树,将返回的树根赋给root
    84     vector<int> vctchar;
    85     cout << endl << "对应的Huffman编码如下:" << endl;
    86     PrintHuffman(root, vctchar);
    87 
    88     system("pause");
    89 }
  • 相关阅读:
    SecureCRT 自定义配置
    deepin 使用笔记
    TotalCommander 使用笔记
    不同环境下MySQL 表名大小写敏感问题
    Windows / Linux 下查看文件 MD5
    设置ll命令日期格式 并友好显示文件大小
    scp 常用命令
    【C++ IO机制】stream_buf 解析
    d
    【C++ IO机制】标准IO库(C库函数)
  • 原文地址:https://www.cnblogs.com/yuanshuang/p/5388895.html
Copyright © 2020-2023  润新知