来自于/*小甲鱼数据结构与算法视频讲解*/
//decode(); 函数为自己编写
//对字符进行哈弗曼编码,由于计算机用8bits存储一个char字符,so,一共可以有256种字符,但ASCII码表中只有128个字符。在本程序中用char code[256];存储各个字符编码的结果,其实也可以用128位,即char code[128].因为:总共有128个字符,建立哈弗曼树时,树最多有128层,这意味着最底层的叶子节点的编码位数为127.所以定义code[128]刚刚好存储编码结果(c风格字符串最后还有一个'\0'结尾标识)。
</pre><pre name="code" class="cpp"><pre name="code" class="cpp">//
/******main.cpp******/
/
#include <stdio.h>
#include <stdlib.h>
#include "huffman.h"
#include "queue.h"
void main()
{
htTree* codeTree=buildTree("I love FishC.com!");
hlTable* codeTable=buildTable(codeTree);
encode(codeTable,"I love FishC.com!");
decode(codeTree,"100011001110010000101011010010100000101011111011111101100101101110");
}
</pre><pre name="code" class="cpp">/
/******queue.h******/
/
#include "huffman.h"
#define TYPE htNode*
#define MAX_SZ 256
typedef struct _pQueueNode{
TYPE val;
unsigned int priority;
struct _pQueueNode *next;
} pQueueNode;
typedef struct _pQueue{
unsigned int size;
pQueueNode *first;
} pQueue;
void initPQueue(pQueue **queue);
void addPQueue(pQueue **queue,TYPE val,unsigned int priority);
TYPE getPQueue(pQueue **queue);
///
/******huffman.h******/
///
#ifndef _HUFFMAN_H
#define _HUFFMAN_H
typedef struct _htNode{
char symbol;
struct _htNode *left,*right;
} 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* inputString);
hlTable* buildTable(htTree *huffmanTree);
void encode(hlTable *table,char *stringToEncode);
void decode(htTree *tree,char *stringToDecode);
void traverseTree(htNode *treeNode,hlTable **table,int j,char code[256]);
#endif
/
/******queue.cpp******/
/
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
void initPQueue(pQueue **queue)
{
(*queue)->first=NULL;
(*queue)->size=0;
return;
}
void addPQueue(pQueue **queue,TYPE val,unsigned int priority)
{
if((*queue)->size==MAX_SZ)
{
printf("\nQueue is full!\n");
return;
}
pQueueNode *aux=(pQueueNode*)malloc(sizeof(pQueueNode));
if(!aux) return;
aux->priority=priority;
aux->val=val;
if((*queue)->size==0 || (*queue)->first==NULL)
{
aux->next=NULL;
(*queue)->first=aux;
(*queue)->size=1;
}
else
{
if(priority<=(*queue)->first->priority)
{
aux->next=(*queue)->first;
(*queue)->first=aux;
(*queue)->size++;
return;
}
else
{
pQueueNode *iterator=(*queue)->first;
while(iterator->next!=NULL)
{
if(priority<=iterator->next->priority)
{
aux->next=iterator->next;
iterator->next=aux;
(*queue)->size++;
return;
}
iterator=iterator->next;
}
if(iterator->next==NULL)
{
aux->next=NULL;
iterator->next=aux;
(*queue)->size++;
return;
}
}
}
}
TYPE getPQueue(pQueue **queue)
{
TYPE returnValue;
if((*queue)->size>0)
{
returnValue=(*queue)->first->val;
(*queue)->first=(*queue)->first->next;
(*queue)->size--;
}
else
printf("\nQueue is empty!\n");
return returnValue;
}
/******huffman.cpp******/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "huffman.h"
#include "queue.h"
htTree* buildTree(char* inputString)
{
int* probability=(int*)malloc(256*sizeof(int));
int i;
for(i=0;i<256;++i)
probability[i]=0;
for(i=0;inputString[i]!='\0';++i)
probability[(unsigned char)inputString[i]]++;
pQueue *huffmanQueue=(pQueue*)malloc(sizeof(pQueue));
initPQueue(&huffmanQueue);
for(i=0;i<256;++i)
{
if(probability[i]!=0)
{
htNode *aux=(htNode*)malloc(sizeof(htNode));
aux->left=NULL;
aux->right=NULL;
aux->symbol=(char)i;
addPQueue(&huffmanQueue,aux,probability[i]);
}
}
free(probability);
while(huffmanQueue->size!=1)
{
int priority=huffmanQueue->first->priority;
priority+=huffmanQueue->first->next->priority;
htNode *left=getPQueue(&huffmanQueue);
htNode *right=getPQueue(&huffmanQueue);
htNode *newNode=(htNode*)malloc(sizeof(htNode));
if(!newNode) return NULL;
newNode->left=left;
newNode->right=right;
addPQueue(&huffmanQueue,newNode,priority);
}
htTree *tree=(htTree*)malloc(sizeof(htTree));
if(!tree) return NULL;
tree->root=getPQueue(&huffmanQueue);
return tree;
}
hlTable* buildTable(htTree *huffmanTree)
{
hlTable *table=(hlTable*)malloc(sizeof(hlTable));
if(!table) return NULL;
table->first=NULL;
table->last=NULL;
char code[256];
int j=0;
traverseTree(huffmanTree->root,&table,j,code);
return table;
}
void traverseTree(htNode *treeNode,hlTable **table,int j,char code[256])
{
if(treeNode->left==NULL && treeNode->right==NULL)
{
code[j]='\0';
hlNode *aux=(hlNode*)malloc(sizeof(hlNode));
aux->code=(char*)malloc(sizeof(char)*(strlen(code)+1));
strcpy(aux->code,code);
aux->symbol=treeNode->symbol;
aux->next=NULL;
if((*table)->first==NULL)
{
(*table)->first=aux;
(*table)->last=aux;
}
else
{
(*table)->last->next=aux;
(*table)->last=aux;
}
}
if(treeNode->left!=NULL)
{
code[j]='0';
traverseTree(treeNode->left,table,j+1,code);
}
if(treeNode->right!=NULL)
{
code[j]='1';
traverseTree(treeNode->right,table,j+1,code);
}
}
void encode(hlTable *table,char *stringToEncode)
{
hlNode *traversal;
int i;
printf("Encoding.......\n\nInput string: \n%s\n\nEncoded string: \n",stringToEncode);
for(i=0;stringToEncode[i]!='\0';++i)
{
traversal=table->first;
while(traversal->symbol!=stringToEncode[i])
traversal=traversal->next;
printf("%s",traversal->code);
}
printf("\n");
}
void decode(htTree *tree,char *stringToDecode)
{
htNode *t=tree->root;
if(!t) return;
int i;
for(i=0;stringToDecode[i]!='\0';++i)
{
if(stringToDecode[i]=='0')
{
t=t->left;
if(t->left==NULL && t->right==NULL)
{
printf("%c",t->symbol);
t=tree->root;
}
}
else if(stringToDecode[i]=='1')
{
t=t->right;
if(t->left==NULL && t->right==NULL)
{
printf("%c",t->symbol);
t=tree->root;
}
}
}
}
程序执行结果: