huffman.h
#pragma once
#include"stdafx.h"
typedef struct _htNode
{
char symbol;
struct _htNode *lchild;
struct _htNode *rchild;
}htNode;
typedef struct _htTree{
htNode *root;
}htTree;
typedef struct _hlNode
{
char symbol;
char* code;
struct _hlNode* next;
}hlNode;
typedef struct _hlTable
{
hlNode *first;
hlNode *last;
}hlTable;
htTree* buildTree(char* strs);
hlTable* buildTable(htTree* codeTree);
void encode(hlTable* codeTable, char*str);
void decode(htTree*codeTree, char *code);
void traversing(htNode* codeNode, hlTable *table, int level, char code[]);
char* codeChar(hlTable* codeTable, char str);
优先队列:按权重由小到大排序
#pragma once #include"huffman.h" #define TYPE htNode* #define MAX_SIZE 256 typedef struct _pQueueNode { unsigned int priority; TYPE val; struct _pQueueNode* next; }pQueueNode; typedef struct _pQueue{ pQueueNode* first; unsigned int size; }pQueue; void initQueue(pQueue**queue); void addQueue(pQueue**queue,TYPE val,unsigned int priority); TYPE getPQueue(pQueue**);
queue.cpp
#include"stdafx.h" #include"queue.h" void initQueue(pQueue**queue){ *queue = new pQueue; (*queue)->first = NULL; (*queue)->size = 0; } void addQueue(pQueue**queue, TYPE val, unsigned int priority){ if ((*queue)->size == MAX_SIZE) { printf("队列已满"); return; } //创建一个pQueueNode pQueueNode * pNode = new pQueueNode; pNode->next = NULL; pNode->priority = priority; pNode->val = val; //按优先级插入 //对空,直接插入 if ((*queue)->size == 0||(*queue)->first == NULL) { (*queue)->first = pNode; (*queue)->size = 1; pNode->next = NULL; } else{ //如果对首元素的优先级大于当前插入的节点,直接插在对首即可 if ((*queue)->first->priority >= priority) { pNode->next = (*queue)->first; (*queue)->first = pNode; (*queue)->size++; } else { pQueueNode *iterator = (*queue)->first; while (iterator->next != NULL && iterator->next->priority < priority) { iterator = iterator->next; } //如果遍历到了对尾,直接插入 if (!iterator->next) { iterator->next = pNode; (*queue)->size++; pNode->next = NULL; } else { pNode->next = iterator->next; iterator->next = pNode; (*queue)->size++; } } } } TYPE getPQueue(pQueue**queue){ TYPE result = NULL; if (!(*queue)->size) { printf("队列为空..."); //return; } else { result = (*queue)->first->val; (*queue)->size--; (*queue)->first = (*queue)->first->next; } return result; }
huffman.cpp
#include"stdafx.h" #include"huffman.h" #include<string.h> #include"queue.h" //建立huffman树 char code[256]; htTree* buildTree(char* strs){ pQueue * queue = NULL; initQueue(&queue); //统计字符出现次数,建立频率表 unsigned int probility[MAX_SIZE]; //初始化频率表 for (int i = 0; i < MAX_SIZE; i++){ probility[i] = 0; } //根据字符的AScii码值对应数组的下标,累加次数 for (unsigned int i = 0; strs[i]!='\0'; i++){ if (strs[i]!='\0') { probility[(unsigned int)strs[i]]++; } } //优先队列填充数据 for (int i = 0; i < MAX_SIZE; i++){ if (probility[i] != 0) { htNode* htnode = new htNode; htnode->lchild = NULL; htnode->rchild = NULL; htnode->symbol = i; addQueue(&queue, htnode, probility[i]); } } //delete[]probility; pQueueNode *iterator = queue->first; while (queue->size >1) { //huffman树节点 htNode* hufNode = new htNode; unsigned int priority = queue->first->priority + queue->first->next->priority; hufNode->lchild = getPQueue(&queue); hufNode->rchild = getPQueue(&queue); addQueue(&queue, hufNode, priority); } htTree * tree = new htTree; tree->root = getPQueue(&queue); return tree; } hlTable* buildTable(htTree* codeTree){ hlTable * codeTable = new hlTable; codeTable->first = NULL; codeTable->last = NULL; traversing(codeTree->root, codeTable, 1, code); return codeTable; } void encode(hlTable* codeTable, char*str){ for (size_t i = 0;str[i]!='\0'; i++) { printf("%s", codeChar(codeTable, str[i])); } } void decode(htTree*codeTree, char *code){ htNode* ptr = codeTree->root; for (size_t i = 0; code[i]!='\0'; i++) { if (ptr->lchild == NULL && ptr->rchild == NULL) { printf("%c", ptr->symbol); ptr = codeTree->root; } if (code[i] == '0') { ptr = ptr->lchild; } if (code[i] == '1') { ptr = ptr->rchild; } } if (ptr->lchild ==NULL && ptr->rchild ==NULL) { printf("%c", ptr->symbol); } } void traversing(htNode* codeNode,hlTable *table,int level,char code[]){ if (codeNode->lchild == NULL && codeNode->rchild == NULL) { code[level - 1] = '\0'; printf("该节点是%c,编码是%s\n",codeNode->symbol,code); hlNode *hl = new hlNode; hl->code = new char[level]; strcpy(hl->code, code); //strcpy(hl->code, code); hl->symbol = codeNode->symbol; if (table->first ==NULL || table->last == NULL) { table->first = hl; table->last = hl; } else { table->last->next = hl; hl->next = NULL; table->last = hl; } } else { if (codeNode->lchild) { code[level - 1] = '0'; traversing(codeNode->lchild, table, level + 1, code); } if (codeNode->rchild) { code[level - 1] = '1'; traversing(codeNode->rchild, table, level + 1, code); } } } char* codeChar(hlTable* codeTable, char str){ hlNode* ptr = codeTable->first; while (ptr!=NULL) { if (ptr->symbol == str) { return ptr->code; } ptr = ptr->next; } return NULL; }
主程序
#include "stdafx.h" #include"huffman.h" #include<stdlib.h> #include<iostream> #include<fstream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { htTree* codeTree = buildTree("Never put off what you can do today until tomorrow"); //traversing(htNode* codeNode,hlTable *table,int level,char code[]) hlTable * codeTable = buildTable(codeTree); encode(codeTable, "what you can do today"); printf("\n"); decode(codeTree, "111101010110001101001000111000010011101000101011001110001111000011011100010110110110001000101011100001010111011110111111"); system("pause"); return 0; }