哈夫曼编码
来源:互联网 发布:零度网络 编辑:程序博客网 时间:2024/06/05 06:07
转载涞源chengyaogen.blog.chinaunix.net
前面一节我们知道了,怎样去创建一个哈夫曼树,这一节我们来看看哈夫曼编码。
思想:得到哈夫曼树后,自顶向下按路径编号,指向左节点的边编号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;
- }
运行结果:
- 信源编码---哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 耐压,成熟
- 为什么String类是不可变的
- java.sql.SQLException: Unknown type '246 in column 0 of 1 in binary-encoded result set的解决办法
- 一些常用函数
- imageView src图片自适应
- 哈夫曼编码
- java的System.getProperty()方法可以获取的值
- 如何:在十六进制字符串与数值类型之间转换(C# 编程指南MSDN)
- Java 面向对象基础小结(四)
- MyEclipse codeStyle设置
- Am335x之u-boot LOGO的增加
- 产品经理必读的九步法(转)
- 【比特币】讨论
- 9种适合工程师的好物