优先队列实现Huffman编码

首先把所有的字符加入到优先队列,然后每次弹出两个结点,用这两个结点作为左右孩子,构造一个子树,子树的跟结点的权值为左右孩子的权值的和,然后将子树插入到优先队列,重复这个步骤,直到优先队列中只有一个结点为止,这个结点就是最终哈夫曼树的根结点。

在定义指针类型的优先队列priority_queue<node*>的时候,需要注意,指针类型默认在比较的时候是直接比较指针的值,也就是地址的大小,要实现比较权值,有两种方法。

一、另外定义一个结构体PNode,结构体中只有一个成员变量: node* p;然后定义priority_queue<PNode>。然后在PNode中重载 < 号就行。

二、重载()运算符。这个方法也要另外写一个结构体。

struct comp

{

    friend bool operator () (const node* a, const node* b)

    {

    }

};

这样,然后定义优先队列的时候对应要这样定义,priority_queue<node*, vector<node*>, comp> que;

贴上我的代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
using namespace std;

struct node
{
    int times;
    char ch;
    node *left, *right;
    node(int t, char c, node* l, node* r)
    {
        times = t;
        ch = c;
        left = l;
        right = r;
    }
    node()
    {
    }
    friend bool operator < (node a, node b)
    {
        return a.times < b.times;
    }
    bool operator () (node a, node b)
    {
        return a.times < b.times;
    }
};
typedef struct PNode
{
    node* p;
    PNode()
    {
    }
    PNode(int t, char c, node* l, node* r)
    {
        p = new node(t, c, l, r);
    }
    friend bool operator < (PNode a, PNode b)
    {
        return a.p->times > b.p->times;
    }
    node* operator -> ()
    {
        return this->p;
    }
    
}Node;
priority_queue<Node> que;
map<char, int> mp;
char str[10005];
int res[100];

void travel(node* p, int arr[], int s)
{
    if(p->left == NULL & p->right == NULL)
    {
        printf("%c: ", p->ch);
        for(int i = 0;i < s;i++)
            printf(i == s-1? "%d\n" : "%d ", arr[i]);
    }
    if(p->left != NULL)
    {
        arr[s] = 0;
        travel(p->left, arr, s + 1);
    }
    if(p->right != NULL)
    {
        arr[s] = 1;
        travel(p->right, arr, s + 1);
    }
}

int main()
{
    /*
     * input: first line, input n, then n lines, a string per line;
     * 
     * output: every character one line: huffman code
     */
    //freopen("in.txt", "r", stdin);
    int n;
    while(scanf("%d", &n) != EOF)
    {
        while(!que.empty())
            que.pop();
        mp.clear();
        
        while(n--)
        {
            scanf("%s", str);
            int len = strlen(str);
            for(int i = 0;i < len;i++)
            {
                mp[str[i]] = mp[str[i]] == 0? 1 :  mp[str[i]] + 1;
            }
        }
        // insert into priority_queue first
        for(map<char, int>::iterator iter = mp.begin();iter != mp.end();iter++)
        {
            //printf("hehe : %c %d\n", iter->first, iter->second);
            que.push(Node(iter->second, iter->first, NULL, NULL));
        }
        // the only one is the result, the huffman tree
        while(que.size() > 1)
        {
            Node a = que.top();
            que.pop();
            Node b = que.top();
            //printf("r: %d %d\n", a->times, b->times);
            que.pop();
            que.push(Node(a->times + b->times, ' ', a.p, b.p));
        }
        Node r = que.top();
        que.pop();
        travel(r.p, res, 0);
    }
    return 0;
}
View Code

 

posted @ 2016-04-21 10:10  xiaxiaosheng  阅读(494)  评论(0编辑  收藏  举报