问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

Huffman编码C语言实现

发布网友 发布时间:2022-05-02 08:55

我来回答

2个回答

热心网友 时间:2023-10-14 18:40

说明:本程序是依据严蔚敏的数据结构(C语言版)上的代码实现的。
#pragmaonce
#include<stdio.h>
#include<tchar.h>
#include<stdlib.h>
#define MAX 100

typedefstruct{ //节点
int weight;
int parent, lchild, rchild;
}HTNode, *HuffmanTree;

typedefchar **HuffmanCode; //字符串数组,用于存储叶子节点的编码

void SelectMinNode(HuffmanTree &HT, int m, int &i1, int &i2) //找出权值最小的两个节点对应的数组下标
{
HuffmanTree p = HT;
int s1, s2;
s1 = s2 = MAX;
i1 = i2 = 1;
for(int i=1; i<=m; i++)
{
if(!(p+i)->parent)
{
if((p+i)->weight < s1)
{
i2 = i;
s1 = (p+i)->weight ;
}
}
}
for(int i=1; i<=m; i++)
{
if(!(p+i)->parent && i!=i2)
{
if((p+i)->weight < s2)
{
i1 = i;
s2 = (p+i)->weight ;
}
}
}
}
void StrCopy(char *p, char *q, int start) //从字符数组中第start个字符开始复制
{
char *c1, *c2;
c1 = p;
while(q[start] != '\0')
{
*c1 = q[start];
c1++;
start++;
}
*c1 = q[start];//别忘了将‘\n’复制过来
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{ //HT赫夫曼树节点数组,HC存储赫夫曼编码,*w 节点权值数组的首地址,n节点个数
int i, i1, i2, m;
HuffmanTree p;
if(n<=1) return;
m = 2 * n -1; //n个叶子节点的赫夫曼树的节点总数为2n-1,可以结合树的度为n-1自己证明。
HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode)); //数组首元素不使用,故多分配一个空间
p = HT + 1;
for(i=1;i<=n;++i,++p,++w) //n个叶子节点初始化
{
p->weight = *w;
p->lchild = 0;
p->rchild = 0;
p->parent = 0;
}
for(;i<=m;++i,++p) //非叶子节点初始化
{
p->weight = 0;
p->lchild = 0;
p->rchild = 0;
p->parent = 0;
}
for(i=n+1;i<=m;++i) //对非叶子节点重新计算
{
SelectMinNode(HT, i-1, i1, i2);
HT[i1].parent = i;
HT[i2].parent = i;
HT[i].lchild = i1;
HT[i].rchild = i2;
HT[i].weight = HT[i1].weight + HT[i2].weight ;
}

///从叶子节点到根节点求赫夫曼编码
char* cd;
int start, c, f;
HC = (HuffmanCode)malloc((n+1)*sizeof(char*));//分配字符指针数组,同样多分配一个
cd = (char*)malloc(n*sizeof(char)); //零时变量,用于存储当前叶子节点的赫夫曼编码
cd[n-1] = '\0';
for(int i=1; i<=n; i++)
{
start = n-1;
for(c=i,f=HT[i].parent; f!=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
}
HC[i] = (char*)malloc((n-start)*sizeof(char));
StrCopy(HC[i], cd, start); //将存储的编码copy给HC的第i个数组
}
free(cd);
}
void PrintHuffmanCode(HuffmanTree HT, HuffmanCode HC, int n) //打印各节点的赫夫曼编码
{
HuffmanCode p;
for(int i=1; i<=n; i++)
{
p = HC;
printf("The weight %d HuffmanCode is: ", HT[i]);
while(*p[i]!='\0')
{
printf("%c",*p[i]);
p[i]++;
}
printf("\n");
}
}
void main()
{
int n = 8;
HuffmanTree HT;
HuffmanCode HC;
int a[8] = {5, 29, 7, 8, 14, 23, 3, 11};//信号源的概率分布,即P={p0, p1,…, pK-1}
HuffmanCoding(HT, HC, a, n);
PrintHuffmanCode(HT, HC, n);
system("pause");}

热心网友 时间:2023-10-14 18:41

#include <stdio.h>

#include <stdlib.h>
#include <io.h>
#define N 255
#define M 2*N - 1
char file[20] = "1.txt";
typedef struct
{
int data; /* 字符值 */
int weight; /* 权重 */
int parent; /* 双亲结点 */
int lchild; /* 左孩子结点 */
int rchild; /* 右孩子结点 */
}Tree;
typedef struct
{
char cd[N];
int start;
}Code;
Tree ht[M];
Code hcd[N];
int cmp(const void*, const void*);
int NumberOfChar();
void Reset();
void InputFile();
void Encode(int);
void Decode(int);
void OutputFile(int);
void PrintHuffmanCode(int);
void CreateHT(int);
void CreateHCode(int);
int main()
{
int x = 0;
int n = 0;
char ch;
Reset();
InputFile();
/* 排序使得有效字符在前面 */
qsort(ht, N, sizeof(Tree), cmp);
/* 记下有效字符的个数 */
n = NumberOfChar();
CreateHT(n);
CreateHCode(n);
OutputFile(n);
PrintHuffmanCode(n);
Encode(n);
Decode(n);
getchar();
return 0;
}
int cmp(const void *a ,const void *b)
{
return (*(Tree *)a).weight < (*(Tree *)b).weight ? 1 : -1;
}
int NumberOfChar()
{
int i, num = 0;
for (i = 0; i < N; i++)
{
if (ht[i].weight > 0) num++;
}
return num;
}
void Reset()
{
int i;
for (i = 0; i < M; i++)
{
ht[i].weight = 0;
ht[i].parent = -1;
ht[i].lchild = -1;
ht[i].rchild = -1;
}
}
void InputFile()
{
FILE *fp;
char ch;
system("cls");
fp = fopen(file, "rt");
/* 读入字符并处理权重 */
while (fscanf(fp, "%c", &ch) != EOF)
{
ht[ch].data = ch;
ht[ch].weight++;
}
fclose(fp);
printf("原文件 %s 读入成功!\n", file);
}
void Encode(int n)
{
int i, k;
char ch;
FILE *fp1, *fp2;
fp1 = fopen(file, "rt");
fp2 = fopen("Encode.txt", "wt+");
/* 一个字符一个字符替换 */
while (fscanf(fp1, "%c", &ch) != EOF)
{
for (i = 0; i < n; i++)
{
if (ht[i].data == ch)
{
for (k = hcd[i].start; k <= n; k++)
{
fprintf(fp2, "%c", hcd[i].cd[k]);
}
}
}
}
fclose(fp1);
fclose(fp2);
printf("编码成功,结果在 Encode.txt 中!\n");
}
void Decode(int n)
{
int i, k;
char ch;
FILE *fp1, *fp2;
fp1 = fopen("Encode.txt", "rt");
fp2 = fopen("Decode.txt", "wt+");
i = 2 * n - 2;
while (fscanf(fp1, "%c", &ch) != EOF)
{
if (ch == '0')
i = ht[i].lchild;
else
i = ht[i].rchild;
/* 找到叶子节点为止 */
if (ht[i].lchild == -1)
{
fprintf(fp2, "%c", ht[i].data);
/* 继续从根节点开始查找 */
i = 2 * n - 2;
}
}
fclose(fp1);
fclose(fp2);
printf("解码成功,结果在 Decode.txt 中!\n");
}
void OutputFile(int n)
{
FILE *fp;
int i, k;
fp = fopen("Huffman_Code.txt", "wt+");
for (i = 0; i < n; i++)
{
fprintf(fp, "%d ", ht[i].data);
for (k = hcd[i].start; k <= n; k++)
{
fprintf(fp, "%c", hcd[i].cd[k]);
}
if (i < n - 1) fprintf(fp, "\n");
}
fclose(fp);
printf("代码表文件 Huffman_Code.txt 生成成功!\n");
}
void PrintHuffmanCode(int n)
{
int i, k;
printf("ASCII \t Char \t HuffmanCode\n");
for (i = 0; i < n; i++)
{
printf("%d \t \"%c\" \t ", ht[i].data, ht[i].data);
for (k = hcd[i].start; k <= n; k++)
{
printf("%c", hcd[i].cd[k]);
}
printf("\n");
}
}
void CreateHT(int n)
{
int i, k ,lmin, rmin;
int min1, min2;
/* 一共有2n-1个节点 */
for (i = n; i < 2 * n - 1; i++)
{
/*lmin和rmin为最小权重的两个节点置*/
min1 = min2 = 0x7FFFFFFF;
lmin = rmin = -1;
for (k = 0; k <= i - 1; k++)
{
/*只在尚未构造二叉树的节点中查找*/
if (ht[k].parent == -1)
{
if (ht[k].weight < min1)
{
min2 = min1;
rmin = lmin;
min1 = ht[k].weight;
lmin = k;
}
else if (ht[k].weight < min2)
{
min2 = ht[k].weight;
rmin = k;
}
}
}
/* 修改2个小权重节点的双亲 */
ht[lmin].parent = i;
ht[rmin].parent = i;
/* 修改双亲的权重 */
ht[i].weight = ht[lmin].weight + ht[rmin].weight;
/* 修改双亲的孩子 */
ht[i].lchild = lmin;
ht[i].rchild = rmin;
}
}
void CreateHCode(int n)
{
int i, f, c;
Code hc;
for (i = 0; i < n; i++)
{
hc.start = n;
c = i;
f = ht[i].parent;
/* 循序直到树根结点 */
while (f != -1)
{
/* 处理左孩子结点 */
if (ht[f].lchild == c)
hc.cd[hc.start--] = '0';
/* 处理右孩子结点 */
else
hc.cd[hc.start--] = '1';
c = f;
f = ht[f].parent;
}
/* start指向哈夫曼编码最开始字符 */
hc.start++;
hcd[i] = hc;
}
}
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
正丁烷和异丁烷的结构简式分别是什么 Win11如何修改桌面文件保存路径?Win11桌面位置路径更改教程 如何修改电脑的盘符名称 如何更改电脑桌面路径win7win7电脑桌面路径怎么更改 i mac 一体机我忘记管理员密码了怎么办,下载不了东西,总是说出现未知错... 中药治疗胃病什么最有效 电脑桌面图标经常不见 湖南湘泉酒的酒质如何? 开办托儿所需要办什么证件 申办托儿所需要准备哪些材料 动漫挂件如何收纳 数据结构课程设计 哈夫曼编码解码 用c语言 huffman编码、译码 (c语言版) 写个哈夫曼编码译码程序 数据结构 c++ 假期生活的作文!800字?怎么写? 本人是护理专业&#39;中级职称是主管护师,目前在学校医务室工作,想问是否可以晋升高级职称,申报项目,论文 怎样加入农村淘宝 怎么在淘宝里和别人的旺旺聊天? 关于淘宝旺旺聊天 (高分聊天高手进)谁告诉我如何用旺旺与顾客聊天 怎样在淘宝旺旺上进行语音聊天? 职工个人使用备用金该如何记账. 员工在总经理那借款作为备用金,月末在财务着报销,该如何处理才对? 某公司设其他应收款-备用金,当公司员工归还借用备用金时,会计分录应怎样做 公司员工借出备用金,借条已入账,收回借款时是否有必要开收据?谢谢回答 想签一份新都的劳动合同 求民主评议党员工作总结 感激涕零 公司跟我们签劳动合同书,合同上说合同是一式三份,但公司一份都没给我们,而且还是空白的,该怎么办呢? 我的户口怎么办? 劳动合同注意事项误选择为无~~ 怎么可以找到雷军讲净水器的ppt? 哈夫曼编码译码C语言编写 如何更改ORACLE 用户的 expired状态 佳能2470一代和二代的区别是什么? 佳能70-2002.8一代这么多年了值得入手二手吗,自动对焦如何,会不会跑焦啥的_百度问一问 单反镜头佳能2470一代测评怎样的 佳能2470头一代是哪年发布的? 求以收获为话题的初中作文 佳能24-70一代和二代画质对比 希望都用过的人发言 有人说24-70二代画 ... 佳能第一代镜头2470能装在5dsr吗 佳能二代24 105 和一代2470,二代2470,哪个好?有没对比评测? 给一篇以“收获”为话题的作文,要700个字左右! 佳能2470镜头多少钱?行货。 佳能2470一代和24105的画质大约差多少 佳能2470价格是多少 2470镜头用佳能一代还是副厂 佳能6d配2470一代,怎么样? 72长做酒格怎么做方便? 装修新房中酒柜的时候要注意一些什么样的问题 酒柜标准深度 酒柜的深度是多少 酒柜格子如何计算
  • 焦点

最新推荐

猜你喜欢

热门推荐