優先隊列求解Huffman編碼 c++

  1. 優先隊列小析

     優先隊列的模板: 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函數

http://blog.csdn.net/daniel_ustc/article/details/17613359編碼

相關文章
相關標籤/搜索