1. 程式人生 > >優先佇列的實現及其在哈夫曼編碼中的應用

優先佇列的實現及其在哈夫曼編碼中的應用

一.優先佇列的實現

template <class T>
class priorityQueue
{
    public:
        priorityQueue();
        virtual ~priorityQueue();
        void insertQueue(T e);
        T pop();
        int getNumOfQueue(){ return num; }
    protected:
        struct node
        {
            T data;
            node *next;
        };
        node* front;
        node* rear;
        int num;
};

template <class T>
priorityQueue<T>::priorityQueue()
{
    num = 0;
    front = rear = new node;
    rear->next = NULL;
}

template <class T>
priorityQueue<T>::~priorityQueue()
{
    node* p = front->next;
    while(p){
        delete front;
        front = p;
        p = front->next;
    }
    delete front;
}

template <class T>
void priorityQueue<T>::insertQueue(T e)
{
    num++;
    node *p = new node, *temp = front->next, *pre = front;
    p->data = e;
    while(temp && temp->data < e){           //此處若是結構體注意要過載  '<'。
        pre = temp;
        temp = temp->next;
    }
    p->next = temp;
    pre->next = p;
}

template <class T>
T priorityQueue<T>::pop()
{
    num--;
    T e = front->next->data;
    node* p = front->next;
    front->next = p->next;
    delete p;

    return e;
}

二.哈夫曼樹的實現:
#include <iostream>
#include "priorityQueue.h"
#include <algorithm>
#include <cstring>

using namespace std;

const int MAXSIZE = 256;

struct HfmNode
{
    char key;
    int priority;
    HfmNode *lchild, *rchild;
};

struct codeNode
{
    char key;
    char code[MAXSIZE];
};

bool cmp(HfmNode a, HfmNode b)
{
    return a.priority < b.priority;
}

bool operator < (HfmNode a, HfmNode b)
{
    return a.priority < b.priority;
}

//建立哈夫曼樹
HfmNode *buildTree(char *str)
{
    int i;
    int priority[MAXSIZE] = {0};
    priorityQueue <HfmNode> que;
    HfmNode *temp = NULL, *ltemp, *rtemp;

    for(i=0; str[i]; i++)
        priority[str[i]]++;

    for(i=0; i<MAXSIZE; i++)
        if(priority[i]){
            temp = new HfmNode;
            temp->key = i;
            temp->priority = priority[i];
            temp->lchild = NULL;
            temp->rchild = NULL;
            que.insertQueue(*temp);
        }

    while(que.getNumOfQueue() > 1){
        temp = new HfmNode;
        ltemp = new HfmNode;
        rtemp = new HfmNode;
        *ltemp = que.pop();
        *rtemp = que.pop();
        temp->priority = ltemp->priority + rtemp->priority;
        temp->lchild = ltemp;
        temp->rchild = rtemp;
        que.insertQueue(*temp);
    }

    temp = new HfmNode;
    *temp = que.pop();
    return temp;
}

bool operator < (codeNode a, codeNode b)
{
    return a.code < b.code;
}

//將字元和所對應的編碼存放起來
void encode(HfmNode *tree, char *code, int i, priorityQueue <codeNode> &table)
{
    if(!tree->lchild && !tree->rchild){
        code[i] = '\0';
        codeNode* temp = new codeNode;
        temp->key = tree->key;
        strcpy(temp->code, code);
        table.insertQueue(*temp);
    }
    else{
        if(tree->lchild){
            code[i] = '0';
            encode(tree->lchild, code, i+1, table);
        }
        if(tree->rchild){
            code[i] = '1';
            encode(tree->rchild, code, i+1, table);
        }
    }
}

//列印字元及其對應編碼
void printfTable(priorityQueue <codeNode> table)
{
     while(table.getNumOfQueue() != 0){
        codeNode temp = table.pop();
        cout<<temp.key<<':'<<temp.code<<endl;
    }
}

//根據編碼找出所代表的字元
void decode(HfmNode* tree, char* str, int i)
{
    if('0' == str[i])
        decode(tree->lchild, str, i+1);
    if('1' == str[i])
        decode(tree->rchild, str, i+1);
    if(!str[i])
        cout<<tree->key;
}
int main()
{
//table 記錄了字元及其所對應的編碼
    priorityQueue <codeNode> table;
    char str[MAXSIZE], code[MAXSIZE];
    cin>>str;

    HfmNode *root = buildTree(str);
    encode(root, code, 0, table);

    printfTable(table);

    cout<<"請輸入字元所對應的編碼:";
    cin>>str;
    cout<<"對應的字元為:";
    decode(root, str, 0);
}