您的位置:首页 > 其它

哈夫曼编码

2014-04-15 12:19 423 查看
前面一节我们知道了,怎样去创建一个哈夫曼树,这一节我们来看看哈夫曼编码。

思想:得到哈夫曼树后,自顶向下按路径编号,指向左节点的边编号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;

}

运行结果:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: