转载请注明来源:http://blog.chinaunix.net/uid-26833883-id-3160434.html
前面一节我们知道了,怎样去创建一个哈夫曼树,这一节我们来看看哈夫曼编码。
思想:得到哈夫曼树后,自顶向下按路径编号,指向左节点的边编号0,指向右节点的边编号1,从根到叶节点的所有边上的0和1连接起来,就是叶子节点中字符的哈夫曼编码。
下图体现了哈夫曼编码的过程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//哈夫曼树结点
typedef struct HuffNode
{
int weight;
char ch;
char code[20];
struct HuffNode *rchild;
struct HuffNode *lchild;
}HuffMan;
//队列设计
typedef struct _node_
{
HuffMan *data;
struct _node_ *next;
}ListNode;
typedef struct
{
ListNode *front;
ListNode *rear;
}Queue;
//create empty queue
Queue *create_empty_queue()
{
ListNode *HList;
Queue *Hqueue;
HList = (ListNode *)malloc(sizeof(ListNode));
HList->next = NULL;
Hqueue = (Queue *)malloc(sizeof(Queue));
Hqueue->front = Hqueue->rear = HList;
return Hqueue;
}
//入队
int EnterQueue(Queue *head,HuffMan *data)
{
ListNode *temp;
temp = (ListNode *)malloc(sizeof(ListNode));
temp->data = data;
temp->next = NULL;
head->rear->next = temp;
head->rear = temp;
return 0;
}
//有序插入结点
int OrderEnterQueue(Queue *head,HuffMan *p)
{
ListNode *m = head->front->next;
ListNode *n = head->front;
ListNode *temp;
while(m)
{
if(m->data->weight < p->weight)
{
m = m->next;
n = n->next;
}
else{
break;
}
}
//插到最后一个结点
if(m == NULL)
{
temp = (ListNode *)malloc(sizeof(ListNode));
temp->data = p;
temp->next = NULL;
n->next = temp;
head->rear = temp;
return 0;
}
//插入中间结点
temp = (ListNode *)malloc(sizeof(ListNode));
temp->data = p;
n->next = temp;
temp->next = m;
return 0;
}
//判断队列是否为空(注意,我们认为队列含有一个结点为空,想想为什么
//这样做?
int _is_empty_queue(Queue *head)
{
if(head->front->next->next == NULL)
{
printf("is_empty_queue\n");
return 1;
}
return 0;
}
//判断队列是否为空
int is_empty_queue(Queue *head)
{
if(head->front == head->rear)
return 1;
else
return 0;
}
//出队
HuffMan *DeleteQueue(Queue * head)
{
ListNode *temp;
temp = head->front;
head->front = temp->next;
free(temp);
temp = NULL;
return head->front->data;
}
//创建哈夫曼树
HuffMan *create_huffman_tree(Queue *head)
{
HuffMan *right,*left,*current;
//循环结束时,队列只含有一个结点
while(!_is_empty_queue(head))
{
left = DeleteQueue(head);
right = DeleteQueue(head);
current = (HuffMan *)malloc(sizeof(HuffMan));
current->weight = left->weight + right->weight;
current->rchild = right;
current->lchild = left;
OrderEnterQueue(head,current);
}
return head->front->next->data;
}
//哈夫曼编码
int HuffmanCode(HuffMan *root)
{
HuffMan *current = NULL;
Queue *queue = NULL;
queue = create_empty_queue();
EnterQueue(queue, root);
while(!is_empty_queue(queue))
{
current = DeleteQueue(queue);
if(current->rchild == NULL && current->lchild == NULL)
{
printf("%c:%d %s\n",current->ch,current->weight,current->code);
}
if(current->lchild)
{
strcpy(current->lchild->code,current->code);
strcat(current->lchild->code,"0");
EnterQueue(queue, current->lchild);
}
if(current->rchild)
{
strcpy(current->rchild->code,current->code);
strcat(current->rchild->code,"1");
EnterQueue(queue, current->rchild);
}
}
return 0;
}
运行结果: