哈夫曼树 (c语言)数据结构
来源:互联网 发布:青岛中山路美食 知乎 编辑:程序博客网 时间:2024/06/07 15:02
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define N 100
typedef struct hfms{
int w;//权值
int p;//父结点下标值
int l;//左子数下标值
int r;//右子树下标值
}hfmsNode;
typedef char *hfmsCode;//动态分配数组储存哈夫曼编码
//定义结构体类型
void select(hfmsNode *ht,int len ,int *s1, int *s2)
{
int i,min1=32767,min2=32767;
for(i=1;i<=len;i++)
{
if(ht[i].w<min1&&ht[i].p==0)
{
min1=ht[i].w;
*s1=i;
}
{
if(ht[i].w<min2&&ht[i].p==0&&i!=*s1)
{
min2=ht[i].w;
*s2=i;
}
}//找到另一个最小的元素
}
hfmsNode *createhfms(int n)//构造哈夫曼树
{
hfmsNode *ht;
int i,s1,s2,m;
if(n<=1)
return NULL;
m=2*n-1;
ht=(hfmsNode *)malloc((2*n)*sizeof(hfmsNode));
for(i=1;i<=m;i++)
{
ht[i].p=0;
ht[i].l=0;
ht[i].r=0;
}//为每个结点的p,l,r赋初值
for(i=1;i<=n;++i)
{
scanf("%d",&(ht[i].w));
}//为每个叶子结点赋初值
for(i=n+1;i<=m;i++)
{
select(ht,i-1,&s1,&s2);
//通过n-1次的选择,删除,合并来创建哈夫曼数
ht[s1].p=i;
ht[s2].p=i;
// ht[k]中选择两个其双亲域为0且权值最小的结点,并返回他们在ht中的序号s1,s2
ht[i].l=s1;
ht[i].r=s2;//s1,s2分别作为i的左右孩子
ht[i].w=ht[s1].w+ht[s2].w;//i的权值作为左右孩子权值之和
}
return ht;
}
void createhfmsCode(hfmsNode *ht,hfmsCode *HC, int n)//哈夫曼树编码
{
int i,c,start;
char *cd;
int f;
HC=(char * *)malloc((n+1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char));//分配临时存储字符编码的动态空间
cd[n-1]='\0';//编码结束符
for(i=1;i<=n;++i)//逐个求字符编码
{
start=n-1;//start开始指向编码结束的位置
c=i;
f=ht[i].p;//f指向结点的双亲
while(f!=0)//从叶子结点开始回溯,直到根结点
{
--start;//回溯一次,start向前指向一个位置
if(ht[f].l==c)
cd[start]='0';//结点c是f的左孩子
else
cd[start]='1';//否则c是f的右孩子
c=f;
f=ht[f].p;//继续向上回溯
}
HC[i]=(char *)malloc((n-start)*sizeof(char));//为第一个字符编码分配空间
strcpy(HC[i], &cd[start]);//把求得的编码的首地址从cd[start]复制到HC的当前行
}
free(cd);
for(i=1;i<=n;i++)
{
printf("权值为%d的叶子结点的哈夫曼编码:%s",ht[i].w,HC[i]);
printf("\n");
}
}
void createhfmsCode1(hfmsNode *ht,int m)//哈夫曼树的译码
{
int i=m,j=0;
char b[N];
getchar();
printf("输入以.结束的编码值:");
scanf("%s",b);
while(b[j]!='.')
{
if(b[j]=='0'{
i=ht[i].l;//为0时是左孩子
}
else
i=ht[i].r;
if(ht[i].l==NULL)
{
printf("该结点的权值为%d",ht[i].w);//左孩子为空时输出该权值
i=m;
}
j++;
}
printf("\n");
}
void menu()
{
printf(" =================================\n");
printf(" ****哈夫曼树编码与译码**** \n");
printf(" 1. 创建哈夫曼树 \n");
printf(" 2. 进行哈夫曼编码 \n");
printf(" 3. 进行哈夫曼译码 \n");
printf(" 4. 退出程序 \n");
printf(" =================================\n");
}
int main()
{
int i,n,m;
hfmsNode *ht;
hfmsCode *HC;
menu();
printf("请输入森林中只有根结点二叉数的数量:");
scanf("%d",&n);
ht=createhfms(n);
m=2*n-1;
createhfmsCode(ht,HC,n);
createhfmsCode1(ht,m);
printf("哈夫曼数每个结点的权值是:");
for(i=1;i<=2*n-1;i++)
{
printf("%3d",ht[i].w);
}
printf("\n");
printf("NO Weight lchild rchild\n");
for(i=1;i<2*n;i++)
{
printf("%d %3d %3d %3d",i,ht[i].w,ht[i].l,ht[i].r);
printf("\n");
}
return 0;
}//主函数
#include<string.h>
#include<malloc.h>
#define N 100
typedef struct hfms{
int w;//权值
int p;//父结点下标值
int l;//左子数下标值
int r;//右子树下标值
}hfmsNode;
typedef char *hfmsCode;//动态分配数组储存哈夫曼编码
//定义结构体类型
void select(hfmsNode *ht,int len ,int *s1, int *s2)
{
int i,min1=32767,min2=32767;
for(i=1;i<=len;i++)
{
if(ht[i].w<min1&&ht[i].p==0)
{
min1=ht[i].w;
*s1=i;
}
}//找到最小的一个元素
for(i=1;i<=len;i++){
if(ht[i].w<min2&&ht[i].p==0&&i!=*s1)
{
min2=ht[i].w;
*s2=i;
}
}//找到另一个最小的元素
}
hfmsNode *createhfms(int n)//构造哈夫曼树
{
hfmsNode *ht;
int i,s1,s2,m;
if(n<=1)
return NULL;
m=2*n-1;
ht=(hfmsNode *)malloc((2*n)*sizeof(hfmsNode));
for(i=1;i<=m;i++)
{
ht[i].p=0;
ht[i].l=0;
ht[i].r=0;
}//为每个结点的p,l,r赋初值
for(i=1;i<=n;++i)
{
scanf("%d",&(ht[i].w));
}//为每个叶子结点赋初值
for(i=n+1;i<=m;i++)
{
select(ht,i-1,&s1,&s2);
//通过n-1次的选择,删除,合并来创建哈夫曼数
ht[s1].p=i;
ht[s2].p=i;
// ht[k]中选择两个其双亲域为0且权值最小的结点,并返回他们在ht中的序号s1,s2
ht[i].l=s1;
ht[i].r=s2;//s1,s2分别作为i的左右孩子
ht[i].w=ht[s1].w+ht[s2].w;//i的权值作为左右孩子权值之和
}
return ht;
}
void createhfmsCode(hfmsNode *ht,hfmsCode *HC, int n)//哈夫曼树编码
{
int i,c,start;
char *cd;
int f;
HC=(char * *)malloc((n+1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char));//分配临时存储字符编码的动态空间
cd[n-1]='\0';//编码结束符
for(i=1;i<=n;++i)//逐个求字符编码
{
start=n-1;//start开始指向编码结束的位置
c=i;
f=ht[i].p;//f指向结点的双亲
while(f!=0)//从叶子结点开始回溯,直到根结点
{
--start;//回溯一次,start向前指向一个位置
if(ht[f].l==c)
cd[start]='0';//结点c是f的左孩子
else
cd[start]='1';//否则c是f的右孩子
c=f;
f=ht[f].p;//继续向上回溯
}
HC[i]=(char *)malloc((n-start)*sizeof(char));//为第一个字符编码分配空间
strcpy(HC[i], &cd[start]);//把求得的编码的首地址从cd[start]复制到HC的当前行
}
free(cd);
for(i=1;i<=n;i++)
{
printf("权值为%d的叶子结点的哈夫曼编码:%s",ht[i].w,HC[i]);
printf("\n");
}
}
void createhfmsCode1(hfmsNode *ht,int m)//哈夫曼树的译码
{
int i=m,j=0;
char b[N];
getchar();
printf("输入以.结束的编码值:");
scanf("%s",b);
while(b[j]!='.')
{
if(b[j]=='0'{
i=ht[i].l;//为0时是左孩子
}
else
i=ht[i].r;
if(ht[i].l==NULL)
{
printf("该结点的权值为%d",ht[i].w);//左孩子为空时输出该权值
i=m;
}
j++;
}
printf("\n");
}
void menu()
{
printf(" =================================\n");
printf(" ****哈夫曼树编码与译码**** \n");
printf(" 1. 创建哈夫曼树 \n");
printf(" 2. 进行哈夫曼编码 \n");
printf(" 3. 进行哈夫曼译码 \n");
printf(" 4. 退出程序 \n");
printf(" =================================\n");
}
int main()
{
int i,n,m;
hfmsNode *ht;
hfmsCode *HC;
menu();
printf("请输入森林中只有根结点二叉数的数量:");
scanf("%d",&n);
ht=createhfms(n);
m=2*n-1;
createhfmsCode(ht,HC,n);
createhfmsCode1(ht,m);
printf("哈夫曼数每个结点的权值是:");
for(i=1;i<=2*n-1;i++)
{
printf("%3d",ht[i].w);
}
printf("\n");
printf("NO Weight lchild rchild\n");
for(i=1;i<2*n;i++)
{
printf("%d %3d %3d %3d",i,ht[i].w,ht[i].l,ht[i].r);
printf("\n");
}
return 0;
}//主函数
阅读全文
0 0
- 哈夫曼树 (c语言)数据结构
- 数据结构(C语言)
- 数据结构之哈夫曼树(c语言)
- 链表(C语言数据结构)
- 目录(数据结构C语言)
- C语言数据结构--(单链表)
- 数据结构(C语言描述)
- 数据结构:C语言实现构建哈夫曼树
- C语言数据结构之哈夫曼树及其应用
- 数据结构读书笔记(一)(C语言)
- 数据结构读书笔记(二)(C语言)
- 数据结构读书笔记(三)(C语言)
- 数据结构(c语言)—笔记
- 数据结构之队列(C语言)
- 数据结构之希尔排序(C语言)
- 数据结构之快速排序(C语言)
- 数据结构:队列(C语言实现)
- 数据结构(C语言)实现循环队列
- VueJs—常用操作手册
- 动态规划——不同的路径
- 【脚本语言系列】关于Python远程调用,你需要知道的事
- 当你在浏览器中输入Google.com并且按下回车之后发生了什么?
- 替换空格
- 哈夫曼树 (c语言)数据结构
- Valgrind内存泄漏检查及定位利器
- Eclipse搭建HTML5开发环境
- 和数能表示1~23的5个正整数
- TensorFlow入门程序-线性回归
- Unity游戏UI框架(七):消息传递中心
- javascript 面向对象(六)原型的特性和作用
- Windows 系统下配置 pyrouge
- 接口测试入门