哈夫曼编码
来源:互联网 发布:centos下安装图形界面 编辑:程序博客网 时间:2024/05/17 10:27
几天看了下哈夫曼树, 输出费了点功夫 贴代码 留被参考
/*
实现对26个字符的编码
*/
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
//haffman tree 节点数据结构
typedef struct Node {
//预编码的字符
char value;
//父节点
struct Node * parent;
struct Node * left;
struct Node * right;
int weight;
char huffcode;
//哈夫曼编码 对于 ascii 表 128 最长8位,最短1位
char huff[9];
} * lnode;
//全部ASCII字符
#define ASCII_SUM 128
//字母表
#define CHARS_SUM 26
//主算法
void huffuman( int weight[]);
//计算权值
void calculate_weight();
//构建haffman树
void Insert_node(lnode *tail, lnode head, lnode cur);
//构建一个节点
lnode make_node( int value, int weight);
//输出编码
void output( lnode root, int h, char *huff);
int
main (void ){
int weight[CHARS_SUM], i ;
for ( i=0; i<CHARS_SUM; i++ ){
weight[i] = 0;
}
calculate_weight(weight);
huffuman(weight);
}
void calculate_weight(int weight[]){
int n;
char buf[1024];
char * pos;
//手动输入,可改写为文件输入
while ( scanf("%s", buf) !=EOF){
pos = buf;
n = strlen(buf);
while ( pos < buf + n ){
//对应各自数组位
weight[*(pos++)-'a']++;
}
}
}
/*待编码列表是个降序排列的链表 头结点是head , 尾节点为tail
有新节点按序插入, 则队列最后两个节点总是要合并的两个最小权值子树
*/
void huffuman( int weight[]){
int i=0, top = -1;
struct Node head;
head.parent = NULL;
lnode tail = &head, cur, temp, s1, s2;
//构建一个有26数的森林
for (i=0;i<CHAS_SUM;i++){
if (weight[i]!=0){
cur = make_node(i, weight[i]);
Insert_node( &tail, &head, cur );
}
}
/*将两最小子树合并,并插入降序链表,循环构建 ,
*如果链表中只有一个节点,构建完成
*/
s1 = tail;
s2 = s1->parent;
//如果地址为头结点 则链表中只有s1一个节点 结束循环
while ( s2 != &head ){
tail = s2->parent;
//构建新节点
cur = make_node(-1, s1->weight + s2->weight);
cur->left = s2;
cur->right = s1;
Insert_node(&tail, &head, cur );
s1 = tail;
s2 = s1->parent;
}
output (tail, -1, tail->huff);
}
void Insert_node(lnode *tail, lnode head, lnode cur){
lnode index = *tail, pre=NULL;
//如果空表,则插入返回
if ( *tail == head ){
cur->parent = head;
*tail= cur;
return;
}
index = *tail;
while( index != head ){
//排序插入
if ( index->weight > cur->weight ){
if ( pre == NULL ){
cur->parent = index;
*tail = cur;
}
else{
pre->parent = cur;
cur->parent = index;
}
return;
}
pre = index;
index = pre->parent;
}
cur->parent = head;
pre->parent = cur;
}
lnode make_node( int value, int weight){
lnode nnode;
nnode = (lnode)malloc( sizeof(struct Node) );
nnode->left = NULL;
nnode->right = NULL;
nnode->parent = NULL;
nnode->value = value;
nnode->weight = weight;
return nnode;
}
void output( lnode root, int h, char *huff){
int i =0, d;
if (root == NULL){
return;
}
strncpy(root->huff, huff, 32);
//判断左孩子,还是右孩子 加入不同的编码值
if ( h == 0){
d = strlen(root->huff);
*(root->huff+d)='0';
*(root->huff+d+1) ='/0';
}
else if ( h==1){
*(root->huff+d)='1';
*(root->huff+d+1) ='/0';
}
if ( root->left ==NULL && root->right==NULL){
printf("%s : %c/n", root->huff, root->value+'a');
return;
}
output( root->left, 0,root->huff);
output( root->right,1,root->huff );
}
- 信源编码---哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- ftp传输数据文件脚本
- 舞出我人生
- Silverlight 4 + RIA Services之商业应用系列----1 使用RIA Services
- 链表
- 什么是多态?
- 哈夫曼编码
- 第一部分 第五章 启动关机,在线求助,执行命令的方式
- NxOgre经验总结(持续更新)
- 逛CSDN少了
- FlexContext.getFlexSession()在servlet的doPost方法中不能用的问题解决
- Ubuntu安装.run文件
- Mapping Letter Frequency on Keyboard
- Ogre贴花
- Mplayer常用快捷键整理