優先佇列的實現及其在哈夫曼編碼中的應用
阿新 • • 發佈:2019-02-10
一.優先佇列的實現
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); }