haffman树c实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 100
#define M 2*N-1
typedef char *HuffmanCode[2*M];
typedef struct
{
int weight;//权值
int parent;//父节点
int Lchild;//左
int Rchild;//右
}HTNode,Huffman[M+1];//huffman树
typedef struct Node
{
int weight;//叶子权值
char c;//叶子
int num;//叶子的2进制码长度
}WNode,WeightNode[N];
void CreatWeight(char ch[],int *s,WeightNode CW,int *p)//生成叶子节点字符与权值
{
int i,j,k;
int tag;
*p=0;//叶子节点数
for(i=0;ch[i]!='\0';i++)//记录字符个数放入CW
{
tag=1;
for(j=0;j<i;j++)
if(ch[j]==ch[i])
{
tag=0;
break;
}
if(tag)
{
CW[++*p].c=ch[i];
CW[*p].weight=1;
for(k=i+1;ch[k]!='\0';k++)
{
if(ch[i]==ch[k])
CW[*p].weight++;//权值++
}
}
}
*s=i;//字符串长
}
void CreateHuffmanTree(Huffman ht,WeightNode w,int n)//建立huffmantree
{
int i,j;
int s1,s2;
for(i=1;i<=n;i++)//初始化
{
ht[i].weight=w[i].weight;
ht[i].parent=0;
ht[i].Lchild=0;
ht[i].Rchild=0;
}
for(i=n+1;i<=2*n-1;i++)
{
ht[i].weight=0;
ht[i].parent=0;
ht[i].Lchild=0;
ht[i].Rchild=0;
}
for(i=n+1;i<=2*n-1;i++)
{
for(j=1;j<=i-1;j++)
if(!ht[j].parent)
break;
s1=j;//找第一个双亲!=0节点
for(;j<=i-1;j++)
if(!ht[j].parent)
s1=ht[s1].weight>ht[j].weight?j:s1;
ht[s1].parent=i;
ht[i].Lchild=s1;
for(j=1;j<=i-1;j++)
if(!ht[j].parent)
break;
s2=j;//找第二个双亲!=0节点
for(;j<=i-1;j++)
if(!ht[j].parent)
s2=ht[s2].weight>ht[j].weight?j:s2;
// printf("s2=%d\n",s2);
ht[s2].parent=i;
ht[i].Rchild=s2;
// intf("rchild=%d\n",ht[i].Rchild);
ht[i].weight=ht[s1].weight+ht[s2].weight;//权值++
}
}
void CrtHuffmanNodeCode(Huffman ht,char ch[],HuffmanCode h,WeightNode weight,int m,int n)//叶子节点编码
{
int i,c,p,start;
char *cd;
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';//末尾=0
for(i=1;i<=n;i++)
{
start=n-1;//cd从末尾开始
c=i;
p=ht[i].parent;//p在n+1——2n-1
while(p)//沿父方向遍历至0
{
start--;//向前
if(ht[p].Lchild==c)//与lchild相同=0
cd[start]='0';
else//=1
cd[start]='1';
c=p;
p=ht[p].parent;
}
weight[i].num=n-start;//二进制码长度
h[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(h[i],&cd[start]);//二进制字符复制到h
}
free(cd);
//system("pause");
}
void CrtHuffmanCode(char ch[],HuffmanCode h,HuffmanCode hc,WeightNode weight,int n,int m)//所有字符编码
{
int i,k;
for(i=0;i<m;i++)
{
for(k=1;k<=n;k++)//从weight[k].c中找与ch[i]相等下标k*
if(ch[i]==weight[k].c)
break;
hc[i]=(char*)malloc((weight[k].num)*sizeof(char));
strcpy(hc[i],h[k]);//复制二进制码
}
}
void TrsHuffmanTree(Huffman ht,WeightNode w,HuffmanCode hc,int n,int m)//译码
{
int i=0,j,p;
while(i<m)
{
p=2*n-1;//从父亲遍历到叶子
for(j=0;hc[i][j]!='\0';j++)
{
if(hc[i][j]=='0')
p=ht[p].Lchild;
else
p=ht[p].Rchild;
}
printf("%c",w[p].c);
i++;
}
}
void main()
{
int i;
int n=0;//叶子数
int m=0;//ch长度
char ch[N];//输入字符
Huffman ht;//huffman二叉树
HuffmanCode h;//叶子编码
HuffmanCode hc;//所有节点编码
WeightNode weight;//叶子信息
printf("Huffman\n please intput inf\n");
gets(ch);
CreatWeight(ch,&m,weight,&n);
for(i=1;i<=n;i++)//输出叶子字符和权
printf("%c",weight[i].c);
printf("\nweight");
for(i=1;i<=n;i++)
printf("%d",weight[i].weight);
CreateHuffmanTree(ht,weight,n);
printf("\ti\tweight\tparent\tLChild\tRChild\n");
for(i=1;i<=2*n-1;i++)
printf("\t%d\t%d\t%d\t%d\t%d\n",i,ht[i].weight,ht[i].parent,ht[i].Lchild,ht[i].Rchild);
CrtHuffmanNodeCode(ht,ch,h,weight,m,n);
for(i=1;i<=n;i++)
{
printf("\t%c ",weight[i].c);
printf("%s\n",h[i]);
}
CrtHuffmanCode(ch,h,hc,weight,n,m);
printf("code");
for(i=0;i<m;i++)
printf("%s",hc[i]);
printf("\n");
TrsHuffmanTree(ht,weight,hc,n,m);
}
haffman树c实现的更多相关文章
- Haffman编码(haffman树)
Haffman编码 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去...).现在给你一串字符以及它们所对应的权值 ...
- 哈夫曼(huffman)树和哈夫曼编码
哈夫曼树 哈夫曼树也叫最优二叉树(哈夫曼树) 问题:什么是哈夫曼树? 例:将学生的百分制成绩转换为五分制成绩:≥90 分: A,80-89分: B,70-79分: C,60-69分: D,<60 ...
- java实现Haffman编码
1.先创建一个树节点类(泛型类),为了方便使用集合的排序方法,泛型类要实现泛型接口Comparable,代码如下 package com.hjp.huffman; /** * Created by J ...
- 文件压缩小项目haffman压缩
文件压缩的原理: 文件压缩总体可以分为有损压缩和无损压缩两类,有损压缩是指对mp3等格式的文件,忽略一些无关紧要的信息,只保留一些关键的信息,但并不因此影响用户对于这些mp3格式文件的体验度,无损压缩 ...
- Huffman Tree
哈夫曼(Huffman)树又称最优二叉树.它是一种带权路径长度最短的树,应用非常广泛. 关于Huffman Tree会涉及到下面的一些概念: 1. 路径和路径长度路径是指在树中从一个结点到另一个结点所 ...
- ZJOI2019一轮停课刷题记录
Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...
- [数据结构] 大纲 - Stan Zhang 数据结构速通教程
* 注: 本文/本系列谢绝转载,如有转载,本人有权利追究相应责任. 2019年4月8日 P1.1 链表 Link:https://www.cnblogs.com/yosql473/p/10727471 ...
- JPEG编码(二)
来自CSDN评论区http://bbs.csdn.net/topics/190980 1. 色彩模型 JPEG 的图片使用的是 YCrCb 颜色模型, 而不是计算机上最常用的 RGB. 关于色彩模型, ...
- c++实验8 哈夫曼编码-译码器
哈夫曼编码-译码器 此次实验的注释解析多加不少---若对小伙伴们有帮助 希望各位麻烦点个关注 多谢 1.哈夫曼树构造算法为: (1)由给定的n个权值{w1,w2,…,wn}构造n棵只有根结点的二叉树, ...
随机推荐
- 手势交互之GestureDetector
GsetureDetector 一.交互过程 触屏的一刹那,触发MotionEvent事件 被OnTouchListener监听,在onTouch()中获得MotionEvent对象 GestureD ...
- JAVA HashMap详细介绍和示例
http://www.jb51.net/article/42769.htm 我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap. 第1部分 HashMa ...
- 关于mssql数据库锁和事务隔离级别
事务隔离级别有4种,这4种级别只是对于读操作,也就是select有不同程度的支持, 读未提交:不会对事务里读出来的数据附加任何锁 读已提交:会对事务里读出来的数据附加共享锁,读完就释放共享锁,其他事务 ...
- 详解SQL Server 2005 Express下的事件探查器
安装Visual Studio 2008会有附带的SQL Server 2005 Express版 我们开发一般都用那个都不单独安装SQL Server的 大家都知道express版的sql是没有 事 ...
- [转]MySQL数据库备份和还原的常用命令小结
MySQL数据库备份和还原的常用命令小结,学习mysql的朋友可以参考下: 备份MySQL数据库的命令 mysqldump -hhostname -uusername -ppassword datab ...
- Java设计模式(学习整理)---工厂模式
1.工厂模式 1.1 为什么使用工厂模式? 因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时 ...
- Wdcp缺少mod_rewite模块
1.下载apache源码包,解压并查找到mod_rewrite.c文件 tar -zxvf httpd-2.2.27.tar.gz cd httpd-2.2.27 [root@localhost ht ...
- 手机端的META你有多了解?
我们先来简单了解下meta标签:meta指元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. 标签位于文档的头部,不包含任何内容. 标签的属性定 ...
- hdu3652B-number
Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal for ...
- 转:PHP如何阻止用户上传成人照片或者裸照
原文来自于:http://www.hackbase.com/tech/2014-10-12/69367.html 当前,网络淫秽色情信息屡禁不止.屡打不绝,严重危害未成年人身心健康,严重败坏社会风气, ...