哈夫曼编码
来源:互联网 发布:激战2优化补丁 编辑:程序博客网 时间:2024/06/05 22:55
前面一节我们知道了,怎样去创建一个哈夫曼树,这一节我们来看看哈夫曼编码。
思想:得到哈夫曼树后,自顶向下按路径编号,指向左节点的边编号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;
- }
运行结果:
0 0
- 信源编码---哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 用命令行启动调试器
- 消息SW WM M区别
- PHP把金额数字转换成大写形式
- Rose与PowerDesigner:两款建模工具的对比
- ubuntu piix4_smbus: Host SMBus controller not enabled!
- 哈夫曼编码
- java之数据类型与数组
- 大神之路-Android优质学习资源、项目和网站大整合(Android学习以来的全面资料整理)
- 哈夫曼树
- Keyguard之LockPatternView学习
- 用SQL语句添加删除修改字段
- 第五周
- linux中源码安装mysql,并启动多个实例
- hive导入 nginx 或 apache 日志