優先隊列的模板: template <class T, class Container = vector<T>,class Compare = less<typename Container::value_type> > class priority_queue;node
能夠看出priority_queue的模板聲明帶有三個參數,T爲數據類型,Container爲保存數據的容器,,Compare爲元素比較方式,其中Container必須是用數組實現的容器,好比vector,deque,不能用list.STL裏面容器默認用的是 vector. 比較方式默認用 operator< ,因此若是你把後面倆個參數 缺省的話,優先隊列就是大頂堆。若是要用到小頂堆,則通常要把模板的三個參數都帶進去。STL裏面定義了一個仿函數 greater<Type>,對於基本類型能夠用這個仿函數聲明小頂堆。引用自(DanielWang_).
在求解Huffman編碼裏面,咱們須要用到小頂堆性質,並且元素仍是指針元素.所以咱們使用以下的方式定義優先隊列,把模板的三個參數都帶進去,而且還自定義了仿函數.
typedef struct HTNode{ char c; unsigned int freq; HTNode *lchild, *rchild; //構造函數 HTNode(char key='\0', unsigned int fr=0, HTNode *l=NULL, HTNode *r=NULL): c(key),freq(fr),lchild(l),rchild(r){}; }HTNode,*pNode; //重載優先隊列裏的比較運算符 struct cmp{ bool operator()(pNode node1, pNode node2){ return node1->freq > node2->freq; } }; //含有指針類型的優先隊列 priority_queue<pNode, vector<pNode>, cmp> pq;
2. 具體實現代碼 ios
在打印Huffman 編碼的時候,還用到了string的一個函數,erase,即刪除某個字符.由於end()返回string的最後一個字符的下一個位置,那麼就能夠用以下的方法刪除最後一個字符.
str.erase(str.end()-1); //刪除最後一個字符
************************************************************************* > File Name: Huffman_code_pg.cpp > Author: He Xingjie > Mail: gxmshxj@163.com > Created Time: 2014年06月06日 星期五 08時57分01秒 > Description: ************************************************************************/ #include<iostream> #include<queue> #include<vector> #include<cstdio> #include<stack> using namespace std; typedef struct HTNode{ char c; unsigned int freq; HTNode *lchild, *rchild; //構造函數 HTNode(char key='\0', unsigned int fr=0, HTNode *l=NULL, HTNode *r=NULL): c(key),freq(fr),lchild(l),rchild(r){}; }HTNode,*pNode; //重載優先隊列裏的比較運算符 struct cmp{ bool operator()(pNode node1, pNode node2){ return node1->freq > node2->freq; } }; //含有指針類型的優先隊列 priority_queue<pNode, vector<pNode>, cmp> pq; void HuffmanCode(int n) { pNode l, r; //從優先隊列中找出優先級最小的兩個元素,合併,並 //把它加入到優先隊列中 while (pq.size() > 1) { pNode z = new HTNode; l = pq.top(); pq.pop(); r = pq.top(); pq.pop(); z->lchild = l; z->rchild = r; z->freq = l->freq + r->freq; pq.push(z); } } void PrintCode(pNode t, string str) { //中序遞歸遍歷HuffmanTree求解HuffmanCode if (t == NULL) return; if (t->lchild) { str += '0'; PrintCode(t->lchild, str); } //葉子節點 if (t->lchild == NULL && t->rchild == NULL) { cout<<t->c<<"'s code: "<<str<<endl; } str.erase(str.end()-1); //刪除最後一個字符 if (t->rchild) { str += '1'; PrintCode(t->rchild, str); } } void DFS(HTNode *t) { HTNode *node; stack<pNode, vector<pNode> > pstack; pstack.push(t); node = pstack.top(); pstack.pop(); while (pstack.size() > 0) { if (node->lchild) { pstack.push(node->lchild); node = node->lchild; } else if(node->rchild) { pstack.push(node->rchild); node = node->rchild; } else { printf("%d ", node->freq); node = pstack.top(); pstack.pop(); } } } int main() { int n, i; FILE *fp; char tmp; string str; fp = fopen("in.txt", "r"); if (fp ==NULL) { printf("fopen error!\n"); return -1; } //輸入大小 fscanf(fp, "%d", &n); fscanf(fp, "%c", &tmp); //輸入數據 for (i=0; i<n; i++) { char c; int freq; pNode p = new HTNode; fscanf(fp, "%c%d", &c, &freq); p->c = c; p->freq = freq; fscanf(fp, "%c", &tmp); pq.push(p); } HuffmanCode(n); PrintCode(pq.top(), str); return 0; }
參考:數組
http://www.cplusplus.com/reference/queue/priority_queue/?kw=priority_queueless
http://blog.csdn.net/liuzhanchen1987/article/details/7856893函數