首先把所有的字符加入到优先队列,然后每次弹出两个结点,用这两个结点作为左右孩子,构造一个子树,子树的跟结点的权值为左右孩子的权值的和,然后将子树插入到优先队列,重复这个步骤,直到优先队列中只有一个结点为止,这个结点就是最终哈夫曼树的根结点。
在定义指针类型的优先队列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 " : "%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 ", 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 ", 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; }