zoukankan      html  css  js  c++  java
  • Huffman树和Huffman编码

    哈夫曼树的构造(哈夫曼算法)
    1.根据给定的n个权值{w1,w2,…,wn}构成二叉树集合F={T1,T2,…,Tn},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树为空.
    2.在F中选取两棵根结点权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为左右子树根结点的权值之和.
    3.在F中删除这两棵树,同时将新的二叉树加入F中.
    4.重复2、3,直到F只含有一棵树为止.(得到哈夫曼树)

    每次选取最小的两个值可以通过优先队列实现,使用优先队列可以使得代码非常简洁。

    建立了哈夫曼树后,可以直接在哈夫曼树上跑一遍得到哈夫曼编码

     1 #include <iostream>
     2 #include <queue>
     3 
     4 using namespace std;
     5 const int maxn = 1e3 + 7;
     6 int n, code[maxn], ans[maxn][maxn];
     7 typedef struct node {
     8     int weight, id;
     9     struct node *lson, *rson;
    10 } *pnode;
    11 
    12 struct cmp {
    13     bool operator()(pnode f1, pnode f2) // 重载括号
    14     {
    15         return (*f1).weight > (*f2).weight; // 等同于less
    16     }
    17 };
    18 
    19 priority_queue<pnode, vector<pnode>, cmp> que;
    20 
    21 pnode get_head() {
    22     for (int i = 1; i <= n; ++i) {
    23         pnode temp = NULL;
    24         temp = (pnode) malloc(sizeof(node));
    25         temp->id = -1;
    26         temp->lson = que.top();
    27         que.pop();
    28         temp->rson = que.top();
    29         que.pop();
    30         temp->weight = temp->lson->weight + temp->rson->weight;
    31         printf("temp->lson->weight = %d temp->rson->weight = %d
    ", temp->lson->weight, temp->rson->weight);
    32         if (que.empty()) return temp;
    33         que.push(temp);
    34     }
    35 }
    36 
    37 void get_ans(pnode h, int dep) {
    38     if (h->lson == NULL && h->rson == NULL) {
    39         int idx = h->id;
    40         for (int i = 0; i < dep; ++i)
    41             ans[idx][i] = code[i];
    42         ans[idx][maxn - 1] = dep;
    43         printf("dep = %d h->weight = %d
    ", dep, h->weight);
    44         return;
    45     }
    46     printf("h->lson->weight = %d h->rson->weight = %d
    ", h->lson->weight, h->rson->weight);
    47     code[dep] = 0;
    48     get_ans(h->lson, dep + 1);
    49     code[dep] = 1;
    50     get_ans(h->rson, dep + 1);
    51 }
    52 
    53 int main() {
    54     freopen("../in.txt", "r", stdin);
    55     while (!que.empty()) que.pop();
    56     for (int i = 0; i < maxn; ++i) code[i] = 1;
    57     cin >> n;
    58     for (int i = 1; i <= n; ++i) {
    59         pnode cnt = NULL;
    60         cnt = (pnode) malloc(sizeof(node));
    61         cnt->lson = cnt->rson = NULL;
    62         cnt->id = i;
    63         cin >> cnt->weight;
    64         que.push(cnt);
    65     }
    66     pnode head = get_head();
    67     printf("total = %d
    ", head->weight);
    68     get_ans(head, 0);
    69     for (int i = 1; i <= n; ++i) {
    70         for (int j = 0; j < ans[i][maxn - 1]; ++j)
    71             printf("%d", ans[i][j]);
    72         printf("
    ");
    73     }
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    RabbitMQ入门-消息订阅模式
    RabbitMQ入门-消息派发那些事儿
    RabbitMQ入门-高效的Work模式
    RabbitMQ入门-从HelloWorld开始
    RabbitMQ入门-初识RabbitMQ
    CMake INSTALL 命令设置exe dll lib的安装位置
    VS调试DLL代码使用”附加到进程“
    模型自身面片重合引起的闪烁破损解决方法
    地球表面使用世界坐标系绘制物体闪烁破损处理方法
    3dmax osg格式导出插件 osgExp OpenSceneGraph Max Exporter
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/12258825.html
Copyright © 2011-2022 走看看