前面一节我们知道了,怎样去创建一个哈夫曼树,这一节我们来看看哈夫曼编码。
思想:得到哈夫曼树后,自顶向下按路径编号,指向左节点的边编号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;
- }
运行结果:
相关推荐
### 哈夫曼编码的贪心算法设计 #### 实验背景与意义 哈夫曼编码是一种广泛应用的数据压缩技术,特别是在文件压缩领域有着极其重要的作用。哈夫曼编码利用了贪心算法的思想来构建最优的前缀编码树,进而达到高效...
哈夫曼树与哈夫曼编码是数据结构和算法领域中的一个重要概念,广泛应用于数据压缩、文本编码以及优先队列等场景。哈夫曼编码是一种特殊的前缀编码方法,能够为字符提供一种高效的二进制表示,使得频繁出现的字符具有...
哈夫曼编码计算信源熵及编码效率 哈夫曼编码是一种变长前缀编码方法,它可以根据信源符号的概率分布计算信源熵和编码效率。本文将详细介绍哈夫曼编码的原理、步骤和实现方法。 哈夫曼编码的原理 哈夫曼编码的原理...
哈夫曼编码是一种高效的数据编码方法,主要用于无损数据压缩。它的原理是为每个字符分配一个唯一的二进制编码,使得频繁出现的字符拥有较短的编码,而不常出现的字符则有较长的编码,以此来减少平均编码长度,达到...
哈夫曼编码是一种高效的数据编码方法,主要用于无损数据压缩,尤其在文本和图像处理领域广泛应用。它基于字符出现频率构建最优的二叉树结构,使得频繁出现的字符占用更短的编码,从而提高压缩效率。这个“图像处理...
利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。 从键盘输入若干字符及每个字符出现的频率,...