当前位置:首页 » 编程语言 » 哈夫曼编码算法c语言
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

哈夫曼编码算法c语言

发布时间: 2022-03-07 21:47:55

① 哈夫曼树及哈夫曼编码的C程序实现(数据结构题)

去年做的课程设计,有什么不合要求的自己改改

#include<string.h>
#include<stdlib.h>
#include<stdio.h>

int m,s1,s2;

typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储哈夫曼树
typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表

void Select(HuffmanTree HT,int n) {
int i,j;
for(i = 1;i <= n;i++)
if(!HT[i].parent){s1 = i;break;}
for(j = i+1;j <= n;j++)
if(!HT[j].parent){s2 = j;break;}
for(i = 1;i <= n;i++)
if((HT[s1].weight>HT[i].weight)&&(!HT[i].parent)&&(s2!=i))s1=i;
for(j = 1;j <= n;j++)
if((HT[s2].weight>HT[j].weight)&&(!HT[j].parent)&&(s1!=j))s2=j;
}

void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[], int *w, int n) {
// 算法6.13
// w存放n个字符的权值(均>0),构造哈夫曼树HT,
// 并求出n个字符的哈夫曼编码HC
int i, j;
char *cd;
int p;
int cdlen;

if (n<=1) return;
m = 2 * n - 1;
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0号单元未用
for (i=1; i<=n; i++) { //初始化
HT[i].weight=w[i-1];
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
for (i=n+1; i<=m; i++) { //初始化
HT[i].weight=0;
HT[i].parent=0;
HT[i].lchild=0;
HT[i].rchild=0;
}
puts("\n哈夫曼树的构造过程如下所示:");
printf("HT初态:\n 结点 weight parent lchild rchild");
for (i=1; i<=m; i++)
printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight,
HT[i].parent,HT[i].lchild, HT[i].rchild);
printf(" 按任意键,继续 ...");
getchar();
for (i=n+1; i<=m; i++) { // 建哈夫曼树
// 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
// 其序号分别为s1和s2。
Select(HT, i-1);
HT[s1].parent = i; HT[s2].parent = i;
HT[i].lchild = s1; HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
printf("\nselect: s1=%d s2=%d\n", s1, s2);
printf(" 结点 weight parent lchild rchild");
for (j=1; j<=i; j++)
printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight,
HT[j].parent,HT[j].lchild, HT[j].rchild);
printf(" 按任意键,继续 ...");
getchar();
}

//------无栈非递归遍历哈夫曼树,求哈夫曼编码
cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间
p = m; cdlen = 0;
for (i=1; i<=m; ++i) // 遍历哈夫曼树时用作结点状态标志
HT[i].weight = 0;
while (p) {
if (HT[p].weight==0) { // 向左
HT[p].weight = 1;
if (HT[p].lchild != 0) { p = HT[p].lchild; cd[cdlen++] ='0'; }
else if (HT[p].rchild == 0) { // 登记叶子结点的字符的编码
HC[p] = (char *)malloc((cdlen+1) * sizeof(char));
cd[cdlen] ='\0'; strcpy(HC[p], cd); // 复制编码(串)
}
} else if (HT[p].weight==1) { // 向右
HT[p].weight = 2;
if (HT[p].rchild != 0) { p = HT[p].rchild; cd[cdlen++] ='1'; }
} else { // HT[p].weight==2,退回退到父结点,编码长度减1
HT[p].weight = 0; p = HT[p].parent; --cdlen;
}
}
} // HuffmanCoding
void main() {
HuffmanTree HT;HuffmanCode *HC;int *w,n,i;
puts("输入结点数:");
scanf("%d",&n);
HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
w = (int *)malloc(n*sizeof(int));
printf("输入%d个结点的权值\n",n);
for(i = 0;i < n;i++)
scanf("%d",&w[i]);
HuffmanCoding(HT,HC,w,n);
puts("\n各结点的哈夫曼编码:");
for(i = 1;i <= n;i++)
printf("%2d(%4d):%s\n",i,w[i-1],HC[i]);
getchar();
}

② Huffman编码c语言实现

说明:本程序是依据严蔚敏的数据结构(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); //将存储的编码给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");}

③ 哈夫曼编码 C源代码

#include <stdio.h>
#define MAXBIT 10 /*定义哈夫曼编码的最大长度*/
#define MAXVALUE 10000 /*定义最大权值*/
#define MAXLEAF 30 /*定义哈夫曼树中最多叶子节点个数*/
#define MAXNODE MAXLEAF*2-1 /*哈夫曼树最多结点数*/
typedef struct { /*哈夫曼编码信息的结构*/
int bit[MAXBIT];
int start;}Hcodetype;
typedef struct { /*哈夫曼树结点的结构*/
int weight;
int parent;
int lchild;
int rchild;
}Hnodetype;
void huffmantree(Hnodetype huffnode[MAXNODE],int n) /*构造哈夫曼树的函数*/
{
int i,j,m1,m2,x1,x2;
for(i=0;i<2*n-1;i++) /*存放哈夫曼树结点的数组huffnode[]初始化*/
{
huffnode[i].weight=0;
huffnode[i].parent=-1;
huffnode[i].lchild=-1;
huffnode[i].rchild=-1;
}
for(i=0;i<n;i++) /*输入入N个叶子节点的权值*/
{
printf("please input %d character's weight\n",i);
scanf("%d",&huffnode[i].weight);
}
for(i=0;i<n-1;i++) /*开始循环构造哈夫曼树*/
{
m1=m2=MAXVALUE;
x1=x2=0;
for(j=0;j<n+i;j++)
{
if(huffnode[j].weight<m1&&huffnode[j].parent==-1)
{
m2=m1;x2=x1;m1=huffnode[j].weight;x1=j;
}
else if(huffnode[j].weight<m2&&huffnode[j].parent==-1)
{
m2=huffnode[j].weight;x2=j;
}
}
huffnode[x1].parent=n+i;
huffnode[x2].parent=n+i;
huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight;
huffnode[n+i].lchild=x1;
huffnode[n+i].rchild=x2;
}
}
void main()
{
Hnodetype huffnode[MAXNODE];
Hcodetype huffcode[MAXLEAF],cd;
int i,j,c,p,n;
printf("please input n\n");
scanf("%d",&n); /*输入叶子节点个数*/
huffmantree(huffnode,n); /*建立哈夫曼树*/
for(i=0;i<n;i++) /*该循环求每个叶子节点对应字符的哈夫曼编码*/
{
cd.start=n-1;c=i;
p=huffnode[c].parent;
while(p!=-1)
{
if(huffnode[p].lchild==c) cd.bit[cd.start]=0;
else cd.bit[cd.start]=1;
cd.start--;c=p;
p=huffnode[c].parent;
}
for(j=cd.start+1;j<n;j++) /*保存求出的每个叶节点的哈夫曼编码和编码的起始位*/
huffcode[i].bit[j]=cd.bit[j];
huffcode[i].start=cd.start;
}
for(i=0;i<n;i++) /*输出每个叶子节点的哈夫曼编码*/
{
printf("%d character is:",i);
for(j=huffcode[i].start+1;j<n;j++)
printf("%d",huffcode[i].bit[j]);
printf("\n");
}
}

④ 哈夫曼编码和译码c语言的源程序

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <malloc.h>
#define NULL 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAX_NUM 10000
#define MAX 60
typedef int Status;
typedef char **HuffmanCode;
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef struct{
HuffmanTree HT;
char *c;
int longth;
HuffmanCode HC;
}Huffman;
void Select(HuffmanTree HT,int end,int *s1,int *s2)
{
int i;
int min1=MAX_NUM;
int min2;
for (i=1;i<=end;i++)
{
if (HT[i].parent==0&&HT[i].weight<min1)
{
*s1=i;
min1=HT[i].weight;
}
}
min2=MAX_NUM;
for(i=1;i<=end;i++)
{
if(HT[i].parent==0&&(*s1!=i)&&min2>HT[i].weight)
{
*s2=i;
min2=HT[i].weight;
}
}
}
Huffman HuffmanCoding(Huffman Hfm)
{
/*---------------------------------*/
int i,n,m,s1,s2,start;
int c,f;
char *cd;
n=Hfm.longth;
if(n<=1) return Hfm;
m=2*n-1;

for(i=n+1;i<=m;++i)
{
Select(Hfm.HT,i-1,&s1,&s2);
Hfm.HT[s1].parent=i;
Hfm.HT[s2].parent=i;
Hfm.HT[i].lchild=s1;
Hfm.HT[i].rchild=s2;
Hfm.HT[i].weight=Hfm.HT[s1].weight+Hfm.HT[s2].weight;
}
/*------------------------------------------*/
Hfm.HC=(HuffmanCode)malloc((n+1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;++i)
{
start=n-1;
for(c=i,f=Hfm.HT[i].parent;f!=0;c=f,f=Hfm.HT[f].parent)
{
if(c==Hfm.HT[f].lchild) cd[--start]='0';
else cd[--start]='1';
}
Hfm.HC[i]=(char *)malloc((n-start)*sizeof(char));
strcpy(Hfm.HC[i],&cd[start]);
}
free(cd);
return Hfm;
}
Huffman InputHuffman(Huffman Hfm)
{
int i,n;
clrscr();
printf("\n\n\t\t********************Initial*********************\n");
printf("\tThe chars and weights will be saved in the file \"hfmTree\"\n");
printf("Please input the number of the chars: ");
scanf("%d",&n);
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
Hfm.c=(char *)malloc((n+1)*sizeof(char));
for(i=1;i<=n;i++)
{
printf("Please input the char: ");
scanf("%s",&Hfm.c[i]);
printf("Please input the weight of the char: ");
scanf("%d",&Hfm.HT[i].weight);
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
for(;i<=2*n-1;++i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
Hfm.longth=n;
return Hfm;
}
Huffman InitHuffman(Huffman Hfm)
{
int n,i;
FILE *fp;
fp=fopen("hfmTree","rt");
if(fp==NULL)
{
Hfm=InputHuffman(Hfm);
fp=fopen("hfmTree","wt");
fprintf(fp,"%d\n",Hfm.longth);
for(i=1;i<=Hfm.longth;i++)
fprintf(fp,"%c %d",Hfm.c[i],Hfm.HT[i].weight);
rewind(fp);
}
else
{
fscanf(fp,"%d\n",&n);
Hfm.c=(char *)malloc((n+1)*sizeof(char));
Hfm.HT=(HuffmanTree)malloc((2*n)*sizeof(HTNode));
for(i=1;i<=n;i++)
fscanf(fp,"%s %d",&Hfm.c[i],&Hfm.HT[i].weight);
for(i=1;i<=n;i++)
{
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
for(;i<=2*n-1;++i)
{
Hfm.HT[i].weight=0;
Hfm.HT[i].parent=0;
Hfm.HT[i].lchild=0;
Hfm.HT[i].rchild=0;
}
Hfm.longth=n;
}
fclose(fp);
Hfm=HuffmanCoding(Hfm);
return Hfm;
}

void Output(Huffman Hfm)
{
int i,n;
n=Hfm.longth;
printf("\n\n******************Output the code of the chars****************\n\n");
for(i=1;i<=n;i++)
{
printf("\n");
printf("Char: %c\t",Hfm.c[i]);
printf("Weight: %d\t",Hfm.HT[i].weight);
printf("Code: ");
puts(Hfm.HC[i]);
}
}
void Encoding(Huffman Hfm)
{
int i=0,j=0,n;
char ch[MAX];
FILE *fp,*ffp;
n=Hfm.longth;
printf("\n\n*******************Encoding**************************\n\n");
if((ffp=fopen("ToBeTran","rt"))==NULL)
{
printf("\nPlease input the sentence: ");
scanf("%s",&ch);
printf("\n");
fp=fopen("CodeFile","wt+");
}
else
{
fscanf(ffp,"%s",ch);
fclose(ffp);
}
while(ch[j])
{
for(i=1;i<=n;i++)
if(ch[j]==Hfm.c[i])
{
printf("%s",Hfm.HC[i]);
fprintf(fp,"%s",Hfm.HC[i]);
break;
}
j++;
}
rewind(fp);
fclose(fp);
}
void Decoding(Huffman Hfm)
{
HuffmanTree p;
int i,n;
int j=0;
char d[50];
FILE *fp;
n=Hfm.longth;
printf("\n\n******************Decoding************************\n\n");
if((fp=fopen("CodeFile","rt"))==NULL)
{
printf("Please input the code:");
scanf("%s",&d);
}
else
{
fscanf(fp,"%s",d);
fclose(fp);
}
printf("\nThe file is : ");
fp=fopen("TextFile","wt+");
while(d[j])
{
p=&Hfm.HT[2*n-1];
while(p->lchild||p->rchild)
{
if(d[j]=='0')
{ i=p->lchild; p=&Hfm.HT[i]; }
else
{ i=p->rchild; p=&Hfm.HT[i]; }
j++;
}
printf("%c",Hfm.c[i]);
fprintf(fp,"%c",Hfm.c[i]);
}
fclose(fp);
}
Huffman RebuildHuffman(Huffman Hfm)
{
int n,i;
FILE *fp;
fp=fopen("hfmTree","wt");
Hfm=InputHuffman(Hfm);
fprintf(fp,"%d\n",Hfm.longth);
for(i=1;i<=Hfm.longth;i++)
fprintf(fp,"%c %d",Hfm.c[i],Hfm.HT[i].weight);
rewind(fp);
fclose(fp);
Hfm=HuffmanCoding(Hfm);
return Hfm;
}
int main()
{
Huffman Hfm;
char choice='a';
Hfm=InitHuffman(Hfm);
while(choice!='q')
{
clrscr();
printf("\n\n\n\t\t*************************************\n\n");
printf("\t\t\ta. Encoding:\n\n");
printf("\t\t\tb. Decoding:\n\n");
printf("\t\t\tc. Print all codes:\n\n");
printf("\t\t\td. Rebuild the huffmantree:\n\n");
printf("\t\t\tq. Quit...\n\n");
printf("\n\t\t************************************\n\n");
printf("Please enter your choice: ");
scanf("%s",&choice);
switch(choice)
{
case 'a':
clrscr();
Encoding(Hfm);
printf("\n\n*******Please enter anykey to continue*******\n");
getch(); break;
case 'b':
clrscr();
Decoding(Hfm);
printf("\n\n*******Please enter anykey to continue********\n");
getch(); break;
case 'c':
clrscr();
Output(Hfm);
printf("\n\n*******Please enter anykey to continue********\n");
getch(); break;
case 'd':
clrscr();
Hfm=RebuildHuffman(Hfm);
printf("\n\n********************Initial*********************\n");
getch(); break;
case 'q':
break;
default:
printf(" Your choice is wrong!\n Please enter anykey to choice again!\n");
getch(); break;
}
}
return 0;
}

⑤ 数据结构(C语言)-哈夫曼编码求助!!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char* HuffmanCode;/*动态分配数组,存储哈夫曼编码*/

typedef struct
{
unsigned int weight ; /* 用来存放各个结点的权值*/
unsigned int parent, LChild,RChild ; /*指向双亲、孩子结点的指针*/
}HTNode, * HuffmanTree; /*动态分配数组,存储哈夫曼树*/

void select(HuffmanTree *ht,int n, int *s1, int *s2)
{
int i;
int min;
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0)
{
min = i;
i = n+1;
}
}
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0)
{
if((*ht)[i].weight < (*ht)[min].weight)
min = i;
}
}
*s1 = min;
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0 && i!=(*s1))
{
min = i;
i = n+1;
}
}
for(i=1; i<=n; i++)
{
if((*ht)[i].parent == 0 && i!=(*s1))
{
if((*ht)[i].weight < (*ht)[min].weight)
min = i;
}
}
*s2 = min;
}

void CrtHuffmanTree(HuffmanTree *ht , int *w, int n)
{ /* w存放已知的n个权值,构造哈夫曼树ht */
int m,i;
int s1,s2;
m=2*n-1;
*ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); /*0号单元未使用*/
for(i=1;i<=n;i++)
{/*1-n号放叶子结点,初始化*/
(*ht)[i].weight = w[i];
(*ht)[i].LChild = 0;
(*ht)[i].parent = 0;
(*ht)[i].RChild = 0;
}
for(i=n+1;i<=m;i++)
{
(*ht)[i].weight = 0;
(*ht)[i].LChild = 0;
(*ht)[i].parent = 0;
(*ht)[i].RChild = 0;
} /*非叶子结点初始化*/
/* ------------初始化完毕!对应算法步骤1---------*/

for(i=n+1;i<=m;i++) /*创建非叶子结点,建哈夫曼树*/
{ /*在(*ht)[1]~(*ht)[i-1]的范围内选择两个parent为0且weight最小的结点,其序号分别赋值给s1、s2返回*/
select(ht,i-1,&s1,&s2);
(*ht)[s1].parent=i;
(*ht)[s2].parent=i;
(*ht)[i].LChild=s1;
(*ht)[i].RChild=s2;
(*ht)[i].weight=(*ht)[s1].weight+(*ht)[s2].weight;
}
}/*哈夫曼树建立完毕*/
void outputHuffman(HuffmanTree HT, int m)
{
if(m!=0)
{
printf("%d ", HT[m].weight);
outputHuffman(HT,HT[m].LChild);
outputHuffman(HT,HT[m].RChild);
}
}

void CrtHuffmanCode(HuffmanTree *ht, HuffmanCode *hc, int n)
/*从叶子结点到根,逆向求每个叶子结点对应的哈夫曼编码*/
{
char *cd;
int i;
unsigned int c;
int start;
int p;
hc=(HuffmanCode *)malloc((n+1)*sizeof(char *)); /*分配n个编码的头指针*/
cd=(char * )malloc(n * sizeof(char )); /*分配求当前编码的工作空间*/
cd[n-1]='\0'; /*从右向左逐位存放编码,首先存放编码结束符*/
for(i=1;i<=n;i++) /*求n个叶子结点对应的哈夫曼编码*/
{
start=n-1; /*初始化编码起始指针*/
for(c=i,p=(*ht)[i].parent; p!=0; c=p,p=(*ht)[p].parent) /*从叶子到根结点求编码*/
if( (*ht)[p].LChild == c)
cd[--start]='0'; /*左分支标0*/
else
cd[--start]='1'; /*右分支标1*/
hc[i]=(char *)malloc((n-start)*sizeof(char)); /*为第i个编码分配空间*/
strcpy(hc[i],&cd[start]);
}
free(cd);
for(i=1;i<=n;i++)
printf("%d编码为%s\n",(*ht)[i].weight,hc[i]);
}

void main()
{
HuffmanTree HT;
HuffmanCode HC;
int *w;
int i,n; // the number of elements;
int wei; // the weight of a element;
int m;

printf("input the total number of the Huffman Tree:" );
scanf("%d",&n);
w=(int *)malloc((n+1)*sizeof(int));
for(i=1;i<=n;i++)
{
printf("input the %d element's weight:",i);
fflush(stdin);
scanf("%d",&wei);
w[i]=wei;
}

CrtHuffmanTree(&HT,w,n);
m = 2*n-1;
outputHuffman(HT,m);
printf("\n");
CrtHuffmanCode(&HT,&HC,n);

}

⑥ 哈夫曼编码的C语言实现

  1. 排序;

  2. 生成编码表;

  3. 读取数据比较,编码。

这个题目建议你好好做做,做了水平会提高不少的。

⑦ c语言编程程序(关于哈夫曼编码)

你好!
这是要完成的程序吗?直接可以运行,还是要介绍

⑧ 哈夫曼编码C语言实现

我写了一个注释较为完整且压缩、解压缩比较全面的:

#include <stdio.h>
#include <conio.h>

#define MAX_FILE 5000/* 假设的文件最大长度 */
#define MAXLIST 256/* 最大MAP值 */
#define MAX_HOFFMAN_LENGTH 50/* 哈夫曼编码长度 */
char dictionary[MAXLIST][2]={0};/* Hash映射,[][0]为权值,[][1]为字符 */
char fileContent[MAX_FILE];/* 处理的字符串大小 */
int Hoffman[MAXLIST][MAX_HOFFMAN_LENGTH]={2};/* 哈夫曼编码序列 */
char HoffmanList[MAXLIST]={0};/* 哈夫曼编码对应的字符有序序列 */
char HoffFileCode[MAX_FILE]={0};/* 哈夫曼编码字符串序列 */
char HoffFile[MAX_FILE]={0};
/* 编码到假设的文件的哈夫曼压缩格式: 依次存储 原字符串长度(1字节存储:可扩展到2字节)、哈夫曼编码数(1字节)、每个哈夫曼编码的长度序列、每个哈夫曼编码对应的字符序列、编码过的哈夫曼字符串 */

char GetFile[MAX_FILE]={0};/* 解码序列 */

void ShellSort(char pData[MAXLIST][2],int Count)/* Shell排序,用于准备有序化要构造的编码权值构造哈夫曼树做准备 */
{
int step[4]={9,5,3,1};/* 增量序列 */

int iTemp,cTemp;
int k,s,w,i,j;
for(i=0;i<4;i++)
{
k=step[i];
s=-k;
for(j=k;j<Count;j++)
{iTemp=pData[j][0];
cTemp=pData[j][1];
w=j-k;
if(s==0)
{
s=-k;
s++;
pData[s][0]=iTemp;
pData[s][1]=cTemp;
}
while((iTemp<pData[w][0])&&(w>=0)&&(w<=Count))
{
pData[w+k][0]=pData[w][0];/* 权值交换 */
pData[w+k][1]=pData[w][1];/* 字符交换 */
w=w-k;
}
pData[w+k][0]=iTemp;
pData[w+k][1]=cTemp;
}
}
}

struct TNode/* 哈夫曼树结点 */
{
struct TNode* pNode;
struct TNode* lNode;
struct TNode* rNode;
char dictionary;
char weight;

};

void TNode_init(struct TNode*tn,char dic,char wei)
{
tn->pNode=0;
tn->lNode=0;
tn->rNode=0;
tn->dictionary=dic;
tn->weight=wei;
}
struct LNode/* 链表结点,用于存储哈夫曼树结点,进而构造哈夫曼树(保证每一步链表结点包含的哈夫曼结点都是有序的) */
{
struct LNode* prev;
struct LNode* next;
struct TNode* tnode;

};

void LNode_init(struct LNode* ln)
{
ln->prev=ln->next=0;
ln->tnode=0;
}

int len=0;/* 哈夫曼编码数 */
int deep=-1;/* 深度 */
void Preorder(struct TNode * p);/* 前序遍历 */
void byLeft(struct TNode*p)/* 经由左结点 */
{
deep++;
Hoffman[len][deep]=0;
Preorder(p);

Hoffman[len][deep]=2;
deep--;
}
void byRight(struct TNode*p)/* 经由右结点 */
{

deep++;
Hoffman[len][deep]=1;
Preorder(p);

Hoffman[len][deep]=2;
deep--;
}
void Preorder(struct TNode * p)
{

int i;
if(p->lNode!=0)/* 当左子结点非空则遍历 */
{

byLeft(p->lNode);
}
if(p->rNode!=0)/* 当右子结点非空则遍历 */
{
byRight(p->rNode);
}

if((p->lNode==0)&&(p->rNode==0))/* 当左右结点都为空,则增加哈夫曼编码数到另一个记录 */
{

Hoffman[len][deep+1]=2;
i=0;
for(;Hoffman[len][i]!=2;i++)
{
Hoffman[len+1][i]=Hoffman[len][i];
}
Hoffman[len+1][i]=2;

HoffmanList[len]=p->dictionary;

len++;
}

}

char generateOne(int k)/* 产生k个连续1的二进制串,比如111,1111,111111,用于编码进假设的文件 */
{
char c=0;
for(;k!=0;k--)
{
c|=(1<<(k-1));

}
return c;
}

int compareBits(char b1,char b2,char c,int l,int d)/* 判断由 [b1,b2] 组成的16位二进制数以d为起点,是否是长度为l的c二进制串(哈夫曼编码)的前缀 */
{
unsigned char t=(((((0x00ff&b1)<<8)|(0x00ff&b2))>>(8-d))&0x00ff);
return (((t)&((generateOne(l)<<(8-l))&0xff))==((c<<(8-l))&0xff));
}

int main()
{
struct LNode* t,*p;
struct LNode* head;
struct TNode *tempTNode,*k1;
int i=0,j,k;
unsigned short fileLen=0;
int len=0,l,b1,b2,d;
char c;
int code[500],h=0;
int codeLen=0,total=0;
/* 或许假定的文件字符串向量中的字符串 */

printf("please Enter string to be pressed:");
scanf("%s",&fileContent);

/* Hash进dictionary */

for(;fileContent[i]!='\0';i++,fileLen++)
{

++dictionary[fileContent[i]][0];
dictionary[fileContent[i]][1]=fileContent[i];
}

/* 把Hash了的dictionary向前靠拢 */

{

for(i=0;i!=MAXLIST;i++)
{

if(dictionary[i][0]!=0)
{
dictionary[len][0]=dictionary[i][0];
dictionary[len][1]=dictionary[i][1];
len++;
}
}
}
printf("the number of Huffman's codes:%d\n",len);
/* 对dictionary按权值进行排序 */

ShellSort(dictionary,len);

/* 构造链表,链表中放有序dictionary权值的树结点 */
head=(struct LNode*)malloc(sizeof(struct LNode)),p=head;
LNode_init(head);
head->next=(struct LNode*)malloc(sizeof(struct LNode));
LNode_init(head->next);

tempTNode=(struct TNode*)malloc(sizeof(struct LNode));
TNode_init(tempTNode,dictionary[0][1],dictionary[0][0]);
head->tnode=tempTNode;

{
for(i=0;i!=len-1;i++)
{
p->next->prev=p->next;
p=p->next;

p->next=(struct LNode*)malloc(sizeof(struct LNode));
LNode_init(p->next);

tempTNode=(struct TNode*)malloc(sizeof(struct TNode)) ;
TNode_init(tempTNode,dictionary[i+1][1],dictionary[i+1][0]);
p->tnode=tempTNode;
}
}
free(p->next);
p->next=0;

/* 每次最小权值的前面两个链表结点中的树结点组成一个子树,子树有合权值,子数的根按权值排序进链表*/

for(p=head;p->next!=0;)
{

p->tnode->pNode=(struct TNode*)malloc(sizeof(struct TNode)) ;
TNode_init(p->tnode->pNode,'\0',(p->tnode->weight)+(p->next->tnode->weight));

p->next->tnode->pNode=p->tnode->pNode;
p->tnode->pNode->lNode=p->tnode;
p->tnode->pNode->rNode=p->next->tnode;
head=p->next;
free(p);
p=head;
p->tnode=p->tnode->pNode;
for(t=head;t->next!=0;t=t->next)
{
if(t->tnode->weight>t->next->tnode->weight)
{
k1=t->tnode;
t->tnode=t->next->tnode;
t->next->tnode=k1;
}
}

}

/* 前序遍历构造哈夫曼编码 */
Preorder(p->tnode);

{
for(i=0;i!=len;i++)
dictionary[HoffmanList[i]][0]=i;
}
/* 存储字符串的哈夫曼压缩编码串,并且打包文件格式 */

{
for(i=0;i!=fileLen;i++)
{
int j=dictionary[fileContent[i]][0];
for(k=0;Hoffman[j][k]!=2;k++)
{

HoffFileCode[codeLen]|=(Hoffman[j][k]<<(7-total%8));
code[h++]=Hoffman[j][k];

if(((total+1)%8)==0)
{
HoffFile[1+len*3+1+codeLen]=HoffFileCode[codeLen];
codeLen++;
}
total++;
}

}
}
HoffFile[1+len*3+1+codeLen]=HoffFileCode[codeLen];
HoffFile[0]=(fileLen);

/* 解压缩假定的文件HoffFile成为原字符串序列 */
printf("Huffman's code list:\n");
HoffFile[1]=len;

{
for(i=0,j=0;i!=len;i++,j=0)
{

for(;Hoffman[i][j]!=2;j++);

HoffFile[i+2]=j;
HoffFile[i+2+2*len]=HoffmanList[i];

for( k=0;k!=j;k++)
{

printf("%d",Hoffman[i][k]);
HoffFile[i+2+len]|=(Hoffman[i][k]<<(j-1-k));

}
printf(":%d\n",HoffmanList[i]);

}
}

{
for(i=0,j=0;i!=(HoffFile[0]&0xff);i++)
{
for(k=0;k!=HoffFile[1];k++)
{

l=HoffFile[2+k],d=j%8,b1=HoffFile[j/8+2+HoffFile[1]*3],b2=HoffFile[j/8+1+2+HoffFile[1]*3];

c=HoffFile[HoffFile[1]+2+k];

if(compareBits(b1,b2,c,l,d))
{

j+=HoffFile[2+k];

GetFile[i]=HoffFile[2+HoffFile[1]*2+k];

break;

}
}

}
}
{
printf("Huffman code List Pressed :\n");
for(i=0;i!=h;i++)
{
printf("%c",code[i]);
if((i+1)%8==0)
printf(" ");
}
}
printf("\n");

{
printf("Huffman code packaged:\n");
for(i=0;i!=HoffFile[0]+HoffFile[1]*3;i++)
{
printf("%c",HoffFile[i]);
}
printf("\n");
}

printf("The initial len :%d\n",fileLen);
printf("The string len pressed:%d\n",(h)/8+1);
printf("The rate%.2f\%",((h/8.0+1)/fileLen)*100);

{

printf("The number of bytes:%d\n",(HoffFile[0]&0xff));
printf("The string decoded:");
for(i=0;i!=(HoffFile[0]&0xff);i++)
{
printf("%c",GetFile[i]);
}

printf("\n");

}
getch();
return 1;
}

⑨ huffman编码译码的c语言实现

留个脚印,晚上回去看看

#include <iostream.h>
#include <iomanip.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

//typedef int TElemType;
const int UINT_MAX=1000;
char str[50];

typedef struct
{
int weight,K;
int parent,lchild,rchild;
}HTNode,* HuffmanTree;

typedef char **HuffmanCode;

//-----------全局变量-----------------------
HuffmanTree HT;
HuffmanCode HC;
int w[50],i,j,n;
char z[50];
int flag=0;
int numb=0;

// -----------------求赫夫曼编码-----------------------
struct cou{
char data;
int count;
}cou[50];

int min(HuffmanTree t,int i)
{ // 函数void select()调用
int j,flag;
int k=UINT_MAX; // 取k为不小于可能的值,即k为最大的权值1000
for(j=1;j<=i;j++)
if(t[j].weight<k&&t[j].parent==0)
k=t[j].weight,flag=j;
t[flag].parent=1;
return flag;
}

//--------------------slect函数----------------------
void select(HuffmanTree t,int i,int &s1,int &s2)
{ // s1为最小的两个值中序号小的那个
int j;
s1=min(t,i);
s2=min(t,i);
if(s1>s2)
{
j=s1;
s1=s2;
s2=j;
}
}
// --------------算法6.12--------------------------
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)
{ // w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
int m,i,s1,s2,start;
//unsigned c,f;
int c,f;
HuffmanTree p;
char *cd;
if(n<=1)
return;//检测结点数是否可以构成树
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0号单元未用
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)
p->parent=0;
for(i=n+1;i<=m;++i) // 建赫夫曼树
{ // 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
// 从叶子到根逆向求每个字符的赫夫曼编码
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
// 分配n个字符编码的头指针向量([0]不用)
cd=(char*)malloc(n*sizeof(char)); // 分配求编码的工作空间
cd[n-1]='\0'; // 编码结束符
for(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));
// 为第i个字符编码分配空间
strcpy(HC[i],&cd[start]); // 从cd复制编码(串)到HC
}
free(cd); // 释放工作空间
}
//---------------------获取报文并写入文件---------------------------------
int InputCode()
{
//cout<<"请输入你想要编码的字符"<<endl;
FILE *tobetran;

if((tobetran=fopen("tobetran.txt","w"))==NULL)
{
cout<<"不能打开文件"<<endl;
return 0;
}
cout<<"请输入你想要编码的字符"<<endl;
gets(str);
fputs(str,tobetran);
cout<<"获取报文成功"<<endl;
fclose(tobetran);
return strlen(str);
}

//--------------初始化赫夫曼链表---------------------------------
void Initialization()
{ int a,k,flag,len;
a=0;
len=InputCode();
for(i=0;i<len;i++)
{k=0;flag=1;
cou[i-a].data=str[i];
cou[i-a].count=1;
while(i>k)
{
if(str[i]==str[k])
{
a++;
flag=0;
}
k++;
if(flag==0)
break;

}

if(flag)
{
for(j=i+1;j<len;j++)
{if(str[i]==str[j])
++cou[i-a].count;}
}

}
n=len-a;
for(i=0;i<n;i++)
{ cout<<cou[i].data<<" ";
cout<<cou[i].count<<endl;
}
for(i=0;i<=n;i++)
{*(z+i)=cou[i].data;
*(w+i)=cou[i].count;
}

/* 原来未修改的初始化程序段:
flag=1;
int num;
int num2;
cout<<"下面初始化赫夫曼链表"<<endl<<"请输入结点的个数n:";
cin>>num;
n=num;
w=(int*)malloc(n*sizeof(int));
z=(char*)malloc(n*sizeof(char));
cout<<"\n请依次输入"<<n<<"个字符(字符型):"<<endl;
char base[2];
for(i=0;i<n;i++)
{
cout<<"第"<<i+1<<"个字符:"<<endl;
gets(base);
*(z+i)=*base;
}
for(i=0;i<=n-1;i++)
{
cout<<setw(6)<<*(z+i);
}
cout<<"\n请依次输入"<<n<<"个权值:"<<endl;
for(i=0;i<=n-1;i++)
{
cout<<endl<<"第"<<i+1<<"个字符的权值:";
cin>>num2;
*(w+i)=num2;
}*/
HuffmanCoding(HT,HC,w,n);
//------------------------打印编码-------------------------------------------
cout<<"字符对应的编码为:"<<endl;
for(i=1;i<=n;i++)
{
puts(HC[i]);
}
//--------------------------将赫夫曼编码写入文件------------------------
cout<<"下面将赫夫曼编码写入文件"<<endl<<"...................."<<endl;
FILE *htmTree;
char r[]={' ','\0'};
if((htmTree=fopen("htmTree.txt","w"))==NULL)
{
cout<<"can not open file"<<endl;
return;
}

fputs(z,htmTree);
for(i=0;i<n+1;i++)
{
fprintf(htmTree,"%6d",*(w+i));
fputs(r,htmTree);
}
for(i=1;i<=n;i++)
{
fputs(HC[i],htmTree);
fputs(r,htmTree);
}
fclose(htmTree);
cout<<"已将字符与对应编码写入根目录下文件htmTree.txt中"<<endl<<endl;
}
//---------------------编码函数---------------------------------
void Encoding()
{
cout<<"下面对目录下文件tobetran.txt中的字符进行编码"<<endl;

FILE *tobetran,*codefile;

if((tobetran=fopen("tobetran.txt","rb"))==NULL)
{
cout<<"不能打开文件"<<endl;
}
if((codefile=fopen("codefile.txt","wb"))==NULL)
{
cout<<"不能打开文件"<<endl;
}
char *tran;
i=99;
tran=(char*)malloc(100*sizeof(char));
while(i==99)
{
if(fgets(tran,100,tobetran)==NULL)
{
cout<<"不能打开文件"<<endl;
break;
}
for(i=0;*(tran+i)!='\0';i++)
{
for(j=0;j<=n;j++)
{
if(*(z+j-1)==*(tran+i))
{
fputs(HC[j],codefile);
if(j>n)
{
cout<<"字符错误,无法编码!"<<endl;
break;
}
}
}
}
}
cout<<"编码工作完成"<<endl<<"编码写入目录下的codefile.txt中"<<endl<<endl;
fclose(tobetran);
fclose(codefile);
free(tran);
}
//-----------------译码函数---------------------------------
void Decoding()
{
cout<<"下面对根目录下文件codefile.txt中的字符进行译码"<<endl;
FILE *codef,*txtfile;
if((txtfile=fopen("txtfile.txt","w"))==NULL)
{
cout<<"不能打开文件"<<endl;
}
if ((codef=fopen("codefile.txt","r"))==NULL)
{
cout<<"不能打开文件"<<endl;
}
char *work,*work2,i2;
int i4=0,i,i3;
unsigned long length=10000;
work=(char*)malloc(length*sizeof(char));
fgets(work,length,codef);
work2=(char*)malloc(length*sizeof(char));
i3=2*n-1;
for(i=0;*(work+i-1)!='\0';i++)
{
i2=*(work+i);
if(HT[i3].lchild==0)
{
*(work2+i4)=*(z+i3-1);
i4++;
i3=2*n-1;
i--;
}
else if(i2=='0') i3=HT[i3].lchild;
else if(i2=='1') i3=HT[i3].rchild;
}
*(work2+i4)='\0';
fputs(work2,txtfile);
cout<<"译码完成"<<endl<<"内容写入根目录下的文件txtfile.txt中"<<endl<<endl;
free(work);
free(work2);
fclose(txtfile);
fclose(codef);
}
//-----------------------打印编码的函数----------------------
void Code_printing()
{
cout<<"下面打印根目录下文件CodePrin.txt中编码字符"<<endl;
FILE * CodePrin,* codefile;
if((CodePrin=fopen("CodePrin.txt","w"))==NULL)
{
cout<<"不能打开文件"<<endl;
return;
}
if((codefile=fopen("codefile.txt","r"))==NULL)
{
cout<<"不能打开文件"<<endl;
return;
}

char *work3;
work3=(char*)malloc(51*sizeof(char));
do
{
if(fgets(work3,51,codefile)==NULL)
{
cout<<"不能读取文件"<<endl;
break;
}
fputs(work3,CodePrin);
puts(work3);
}while(strlen(work3)==50);
free(work3);
cout<<"打印工作结束"<<endl<<endl;
fclose(CodePrin);
fclose(codefile);
}
//-------------------------------打印译码函数---------------------------------------------
void Code_printing1()
{
cout<<"下面打印根目录下文件txtfile.txt中译码字符"<<endl;
FILE * CodePrin1,* txtfile;
if((CodePrin1=fopen("CodePrin1.txt","w"))==NULL)
{
cout<<"不能打开文件"<<endl;
return;
}
if((txtfile=fopen("txtfile.txt","r"))==NULL)
{
cout<<"不能打开文件"<<endl;
return;
}
char *work5;
work5=(char*)malloc(51*sizeof(char));
do
{
if(fgets(work5,51,txtfile)==NULL)
{
cout<<"不能读取文件"<<endl;
break;
}
fputs(work5,CodePrin1);
puts(work5);
}while(strlen(work5)==50);
free(work5);
cout<<"打印工作结束"<<endl<<endl;
fclose(CodePrin1);
fclose(txtfile);
}
//------------------------打印赫夫曼树的函数-----------------------
void coprint(HuffmanTree start,HuffmanTree HT)
{
if(start!=HT)
{
FILE * TreePrint;

if((TreePrint=fopen("TreePrint.txt","a"))==NULL)
{cout<<"创建文件失败"<<endl;
return;
}
numb++;//该变量为已被声明为全局变量
coprint(HT+start->rchild,HT);
cout<<setw(5*numb)<<start->weight<<endl;

fprintf(TreePrint,"%d\n",start->weight);
coprint(HT+start->lchild,HT);
numb--;
fclose(TreePrint);
}
}
void Tree_printing(HuffmanTree HT,int w)
{
HuffmanTree p;
p=HT+w;
cout<<"下面打印赫夫曼树"<<endl;
coprint(p,HT);
cout<<"打印工作结束"<<endl;
}
//------------------------主函数------------------------------------
void main()
{
char choice;
while(choice!='q')
{ cout<<"\n******************************"<<endl;
cout<<" 欢迎使用赫夫曼编码解码系统"<<endl;
cout<<"******************************"<<endl;
cout<<"(1)要初始化赫夫曼链表请输入'i'"<<endl;
cout<<"(2)要编码请输入'e'"<<endl;
cout<<"(3)要译码请输入'd'"<<endl;
cout<<"(4)要打印编码请输入'p'"<<endl;
cout<<"(5)要打印赫夫曼树请输入't'"<<endl;
cout<<"(6)要打印译码请输入'y'"<<endl;
if(flag==0)cout<<"\n请先初始化赫夫曼链表,输入'i'"<<endl;
cin>>choice;
switch(choice)
{
case 'i':
Initialization();
break;
case 'e':
Encoding();
break;
case 'd':
Decoding();
break;
case 'p':
Code_printing();
break;
case 't':
Tree_printing(HT,2*n-1);
break;
case 'y':
Code_printing1();
break;
default:
cout<<"input error"<<endl;
}

}
free(z);
free(w);
free(HT);
}

⑩ 哈夫曼编码 c语言 求改正

我这有C++的哈夫曼树,前一段时间的数据结构的作业。