哈夫曼树源代码

哈夫曼树源代码
哈夫曼树源代码

#include

#include

#include

#include

#include typedef struct

{

float weight;

int flag;

int parent;

int lchild;

int rchild;

}huffnode,*HuffmanTree; typedef struct

{

int bits[30];

int start;

}huffcode;

void numbers(int q)

{

int num=10000;

int i,j,x1,x2,n,c,p;

float m1,m2;

char ch,sh;

FILE *fp;

char filename[30];

printf("请给新文件命名:");

scanf("%s",filename);

fp=fopen(filename,"w+");

n=10;

float sum[10]={0};

for(i=1; i<=num; i++)

{

ch=rand()%10;

sum[ch]++;

printf("%c",ch+'0');

fprintf(fp,"%c",ch+'0');//

fclose(fp);

}

fflush(stdin);

printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!");

scanf("%c",&sh);

system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n");

printf("\t\t* 接下来为你计算各个数字权值(请稍等)! *\n");

printf("\t\t********************************* ************");

Sleep(4*1000);

fflush(stdin);

//scanf("%c",&sh);

system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!");

scanf("%c",&sh);

system("cls");

printf("\t\t各数字权值如下:\n");

for(i=0;i

{

printf("\t\t%d\t%f\n",i,sum[i]/10000);

}

scanf("%c",&sh);

huffnode huff_node[19];

huffcode huff_code[10],cd;

for(i=0;i<2*n-1;i++)

{

huff_node[i].weight=0;

huff_node[i].parent=0;

huff_node[i].flag=0;

huff_node[i].lchild=0;

huff_node[i].rchild=0;

}

for(i=0;i

{

huff_node[i].weight=sum[i];

}

for(i=0;i

{

m1=m2=20000;

x1=x2=0;

for(j=0;j

{

if

(huff_node[j].weight

{

m2=m1;

x2=x1;

m1=huff_node[j].weight;

x1=j;

}

else if

(huff_node[j].weight

{

m2=huff_node[j].weight;

x2=j;

}

}

huff_node[x1].parent=n+i;

huff_node[x2].parent=n+i;

huff_node[x1].flag=1;

huff_node[x2].flag=1;

huff_node[n+i].weight=huff_node[x1].weight+huff _node[x2].weight;

huff_node[n+i].lchild=x1;

huff_node[n+i].rchild=x2;

}

for(i=0;i

{

cd.start=n-1;

c=i;

p=huff_node[c].parent;

while(p!=0)

{

if(huff_node[p].lchild==c)

cd.bits[cd.start]=0;

else

cd.bits[cd.start]=1;

cd.start--;

c=p;

p=huff_node[p].parent;

}

cd.start++;

for(j=cd.start;j

huff_code[i].bits[j]=cd.bits[j];

huff_code[i].start=cd.start;

}

puts("各数字的哈夫曼编码是:");

for(i=0;i

{

printf("%d ",i);

for(j=huff_code[i].start;j

printf("%10d",huff_code[i].bits[j]);

printf("\n");

}

HuffmanTree t;

char str[500];

fflush(stdin);

scanf("%c",&sh);

system("cls");

//fflush(stdin);

//scanf("%c",&sh);

puts("\t\t***************************"); puts("\t\t* 下面开始哈夫曼解码*");

puts("\t\t***************************"); for(i=0;i

{

printf("\t%d ",i);

for(j=huff_code[i].start;j

printf("%10d",huff_code[i].bits[j]);

printf("\n");

}

while(1)

{

state2:printf("请输入待解码:");

scanf("%s",str);

int L=strlen(str);

for(j=0;j

{

if(str[j]!='0'&&str[j]!='1'&&str[j]!='\0')

{

puts("待解码中有错误码,请重新输入!");

goto state2;

}

}

j=0;

while(j

{

t=&huff_node[2*n-2];

while(t->lchild||t->rchild)

{

if(str[j]=='0')

{

i=t->lchild;

t=&huff_node[i];

}

else if(str[j]=='1')

{

i=t->rchild;

t=&huff_node[i];

}

else

goto state1;

j++;

}

printf("%d",i);

}

state1:printf("\n");

}

}

void Capital_letters(int q)

{

int num=10000;

int i,j,x1,x2,n,c,p;

float m1,m2;

char ch,sh;

FILE *fp;

char filename[30];

printf("请给新文件命名:");

scanf("%s",filename);

fp=fopen(filename,"w+");

n=26;

float sum[26]={0};

for(i=1; i<=num; i++)

{

ch=rand()%26+'A';

sum[ch-'A']++;

printf("%c",ch);

fprintf(fp,"%c",ch);//

fclose(fp);

}

fflush(stdin);

printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!");

scanf("%c",&sh);

system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n");

printf("\t\t* 接下来为你计算各个字符权值(请稍等)! *\n");

printf("\t\t********************************* ************");

Sleep(4*1000);

fflush(stdin);

//scanf("%c",&sh);

system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!");

scanf("%c",&sh);

system("cls");

printf("\t\t各数权值如下:\n");

for(i=0;i

{

printf("\t\t%c\t%f\n",i+'A',sum[i]/10000);

}

scanf("%c",&sh);

huffnode huff_node[51];

huffcode huff_code[26],cd;

for(i=0;i<2*n-1;i++)

{

huff_node[i].weight=0;

huff_node[i].parent=0;

huff_node[i].flag=0;

huff_node[i].lchild=0;

huff_node[i].rchild=0;

}

for(i=0;i

{

huff_node[i].weight=sum[i];

}

for(i=0;i

{

m1=m2=20000;

x1=x2=0;

for(j=0;j

{

if

(huff_node[j].weight

{

m2=m1;

x2=x1;

m1=huff_node[j].weight;

x1=j;

}

else if

(huff_node[j].weight

{

m2=huff_node[j].weight;

x2=j;

}

}

huff_node[x1].parent=n+i;

huff_node[x2].parent=n+i;

huff_node[x1].flag=1;

huff_node[x2].flag=1;

huff_node[n+i].weight=huff_node[x1].weight+huff _node[x2].weight;

huff_node[n+i].lchild=x1;

huff_node[n+i].rchild=x2;

}

for(i=0;i

{

cd.start=n-1;

c=i;

p=huff_node[c].parent;

while(p!=0)

{

if(huff_node[p].lchild==c)

cd.bits[cd.start]=0;

else

cd.bits[cd.start]=1;

cd.start--;

c=p;

p=huff_node[p].parent;

}

cd.start++;

for(j=cd.start;j

huff_code[i].bits[j]=cd.bits[j];

huff_code[i].start=cd.start;

}

puts("各字符的哈夫曼编码是:");

for(i=0;i

{

printf("%c ",i+'A');

for(j=huff_code[i].start;j

printf("%10d",huff_code[i].bits[j]);

printf("\n");

}

HuffmanTree t;

char str[500];

fflush(stdin);

scanf("%c",&sh);

system("cls");

//fflush(stdin);

//scanf("%c",&sh);

puts("\t\t***************************"); puts("\t\t* 下面开始哈夫曼解码*");

puts("\t\t***************************"); for(i=0;i

{

printf("\t%c ",i+'A');

for(j=huff_code[i].start;j

printf("%10d",huff_code[i].bits[j]);

printf("\n");

}

while(1)

{

state2:printf("请输入待解码:");

scanf("%s",str);

int L=strlen(str);

for(j=0;j

{

if(str[j]!='0'&&str[j]!='1'&&str[j]!='\0')

{

puts("待解码中有错误码,请重新输入!");

goto state2;

}

}

j=0;

while(j

{

t=&huff_node[2*n-2];

while(t->lchild||t->rchild)

{

if(str[j]=='0')

{

i=t->lchild;

t=&huff_node[i];

}

else if(str[j]=='1')

{

i=t->rchild;

t=&huff_node[i];

}

else

goto state1;

j++;

}

printf("%c",i+'A');

}

state1:printf("\n");

}

}

void Lower_letters(int q)

{

int num=10000;

int i,j,x1,x2,n,c,p;

float m1,m2;

char ch,sh;

FILE *fp;

char filename[30];

printf("请给新文件命名:");

scanf("%s",filename);

fp=fopen(filename,"w+");

n=26;

float sum[26]={0};

for(i=1; i<=num; i++)

{

ch=rand()%26+'a';

sum[ch-'a']++;

printf("%c",ch);

fprintf(fp,"%c",ch);//

fclose(fp);

}

fflush(stdin);

printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!");

scanf("%c",&sh);

system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n");

printf("\t\t* 接下来为你计算各个数字权值(请稍等)! *\n");

printf("\t\t********************************* ************");

Sleep(4*1000);

fflush(stdin);

//scanf("%c",&sh);

system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!");

scanf("%c",&sh);

system("cls");

printf("\t\t各数权值如下:\n");

for(i=0;i

{

printf("\t\t%c\t%f\n",i+'a',sum[i]/10000);

}

scanf("%c",&sh);

huffnode huff_node[51];

huffcode huff_code[26],cd;

for(i=0;i<2*n-1;i++)

{

huff_node[i].weight=0;

huff_node[i].parent=0;

huff_node[i].flag=0;

huff_node[i].lchild=0;

huff_node[i].rchild=0;

}

for(i=0;i

{

huff_node[i].weight=sum[i];

}

for(i=0;i

{

m1=m2=20000;

x1=x2=0;

for(j=0;j

{

if

(huff_node[j].weight

{

m2=m1;

x2=x1;

贪心算法构造哈夫曼树

软件02 1311611006 张松彬利用贪心算法构造哈夫曼树及输出对应的哈夫曼编码 问题简述: 两路合并最佳模式的贪心算法主要思想如下: (1)设w={w0,w1,......wn-1}是一组权值,以每个权值作为根结点值,构造n棵只有根的二叉树 (2)选择两根结点权值最小的树,作为左右子树构造一棵新二叉树,新树根的权值是两棵子树根权值之和 (3)重复(2),直到合并成一颗二叉树为 一、实验目的 (1)了解贪心算法和哈夫曼树的定义(2)掌握贪心法的设计思想并能熟练运用(3)设计贪心算法求解哈夫曼树(4)设计测试数据,写出程序文档 二、实验内容 (1)设计二叉树结点数据结构,编程实现对用户输入的一组权值构造哈夫曼树(2)设计函数,先序遍历输出哈夫曼树各结点3)设计函数,按树形输出哈夫曼树 代码: #include #include #include #include typedef struct Node{ //定义树结构 int data; struct Node *leftchild; struct Node *rightchild; }Tree; typedef struct Data{ //定义字符及其对应的频率的结构 int data;//字符对应的频率是随机产生的 char c; }; void Initiate(Tree **root);//初始化节点函数 int getMin(struct Data a[],int n);//得到a中数值(频率)最小的数 void toLength(char s[],int k);//设置有k个空格的串s void set(struct Data a[],struct Data b[]);//初始化a,且将a备份至b char getC(int x,struct Data a[]);//得到a中频率为x对应的字符 void prin(struct Data a[]);//输出初始化后的字符及对应的频率 int n; void main() { //srand((unsigned)time(NULL));

哈夫曼树及其应用(完美版)

数据结构课程设计设计题目:哈夫曼树及其应用 学院:计算机科学与技术 专业:网络工程 班级:网络 131 学号:1308060312 学生姓名:谢进 指导教师:叶洁 2015年7 月12 日

设计目的: 赫夫曼编码的应用很广泛,利用赫夫曼树求得的用于通信的二进制编码称为赫夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是赫夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 1、熟悉树的二叉树的存储结构及其特点。 2、掌握建立哈夫曼树和哈夫曼编码的方法。 设计内容: 欲发一封内容为AABBCAB ……(共长 100 字符,字符包括A 、B 、C 、D 、E 、F六种字符),分别输入六种字符在报文中出现的次数(次数总和为100),对这六种字符进行哈夫曼编码。 设计要求: 对输入的一串电文字符实现赫夫曼编码,再对赫夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵赫夫曼树,此构造过程称为赫夫曼编码。设计实现的功能: 1.以二叉链表存储, 2.建立哈夫曼树; 3.求每个字符的哈夫曼编码并显示。

实验六 哈夫曼树及哈夫曼编码

#include #include #include #define n 6 /* 叶子数目*/ #define m 2*n-1 /* 结点总数*/ #define Maxval 1 /* 最大权值*/ typedef char datatype; typedef struct //定义为结构类型 { float weight; //权值 datatype data; int lchild, rchild, parent; } hufmtree; hufmtree tree[m]; typedef struct { char bits[n]; /* 编码数组位串,其中n为叶子结点数目*/ int start; /* 编码在位串的起始位置*/ datatype data; } codetype; codetype code[n]; HUFFMAN(hufmtree tree[ ]) { int i, j, p1,p2; char ch; float small1,small2,f; for( i=0; i

哈夫曼树编码译码实验报告(DOC)

数据结构课程设计设计题目:哈夫曼树编码译码

目录 第一章需求分析 (1) 第二章设计要求 (1) 第三章概要设计 (2) (1)其主要流程图如图1-1所示。 (3) (2)设计包含的几个方面 (4) 第四章详细设计 (4) (1)①哈夫曼树的存储结构描述为: (4) (2)哈弗曼编码 (5) (3)哈弗曼译码 (7) (4)主函数 (8) (5)显示部分源程序: (8) 第五章调试结果 (10) 第六章心得体会 (12) 第七章参考文献 (12) 附录: (12)

在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。 第二章设计要求 对输入的一串电文字符实现哈夫曼编码,再对哈夫曼编码生成的代码串进行译码,输出电文字符串。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度能尽可能短,即采用最短码。假设每种字符在电文中出现的次数为Wi,编码长度为Li,电文中有n种字符,则电文编码总长度为∑WiLi。若将此对应到二叉树上,Wi为叶结点的权,Li为根结点到叶结点的路径长度。那么,∑WiLi 恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以n种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。设计实现的功能: (1) 哈夫曼树的建立; (2) 哈夫曼编码的生成; (3) 编码文件的译码。

实验三.哈夫曼编码的贪心算法设计

实验四 哈夫曼编码的贪心算法设计(4学时) [实验目的] 1. 根据算法设计需要,掌握哈夫曼编码的二叉树结构表示方法; 2. 编程实现哈夫曼编译码器; 3. 掌握贪心算法的一般设计方法。 实验目的和要求 (1)了解前缀编码的概念,理解数据压缩的基本方法; (2)掌握最优子结构性质的证明方法; (3)掌握贪心法的设计思想并能熟练运用 (4)证明哈夫曼树满足最优子结构性质; (5)设计贪心算法求解哈夫曼编码方案; (6)设计测试数据,写出程序文档。 实验内容 设需要编码的字符集为{d 1, d 2, …, dn },它们出现的频率为 {w 1, w 2, …, wn },应用哈夫曼树构造最短的不等长编码方案。 核心源代码 #include #include #include typedef struct { unsigned int weight; //用来存放各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码 ∑=j i k k a

//选择两个parent为0,且weight最小的结点s1和s2 void Select(HuffmanTree *ht,int n,int *s1,int *s2) { int i,min; for(i=1; i<=n; i++) { if((*ht)[i].parent==0) { min=i; break; } } 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++)

北邮数据结构实验3哈夫曼编码

数据结构实验报告 实验名称:实验3——哈夫曼编码 学生姓名: 班级: 班内序号: 学号: 日期:2013年11月24日 1.实验要求 利用二叉树结构实现赫夫曼编/解码器。 基本要求: 1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个 字符的频度,并建立赫夫曼树 2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每 个字符的编码输出。 3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的 字符串输出。 4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译 码,并输出译码结果。 5、打印(Print):以直观的方式打印赫夫曼树(选作) 6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼 编码的压缩效果。 2. 程序分析 2.1存储结构: struct HNode { char c;//存字符内容 int weight; int lchild, rchild, parent; }; struct HCode

{ char data; char code[100]; }; //字符及其编码结构 class Huffman { private: HNode* huffTree; //Huffman树 HCode* HCodeTable; //Huffman编码表 public: Huffman(void); void CreateHTree(int a[], int n); //创建huffman树 void CreateCodeTable(char b[], int n); //创建编码表 void Encode(char *s, string *d); //编码 void Decode(char *s, char *d); //解码 void differ(char *,int n); char str2[100];//数组中不同的字符组成的串 int dif;//str2[]的大小 ~Huffman(void); }; 结点结构为如下所示: 三叉树的节点结构: struct HNode//哈夫曼树结点的结构体 { int weight;//结点权值 int parent;//双亲指针 int lchild;//左孩子指针 int rchild;//右孩子指针 char data;//字符 }; 示意图为: int weight int parent int lchild int rchild Char c 编码表节点结构:

实验四 哈夫曼树与哈夫曼编码

实验四哈夫曼树与哈夫曼编码 一、实验目的 1、使学生熟练掌握哈夫曼树的生成算法。 2、熟练掌握哈夫曼编码的方法。 二、实验内容 [问题描述] 已知n个字符在原文中出现的频率,求它们的哈夫曼编码。[基本要求] 1. 初始化:从键盘读入n个字符,以及它们的权值,建立Huffman 树。(具体算法可参见教材P147的算法6.12) 2. 编码:根据建立的Huffman树,求每个字符的Huffman 编码。 对给定的待编码字符序列进行编码。 [选作内容] 1. 译码:利用已经建立好的Huffman树,对上面的编码结果译码。 译码的过程是分解电文中的字符串,从根结点出发,按字符’0’和’1’确定找左孩子或右孩子,直至叶结点,便求得该子串相应的字符。 4. 打印 Huffman树。 [测试数据] 利用教材P.148 例6-2中的数据调试程序。可设8种符号分别为A,B,C,D,E,F,G,H。编/译码序列为“CFBABBFHGH”(也可自己设定数据进行测试)。

三、算法设计 1、主要思想:******************赫夫曼树的构造 ********************** (1) 由给定的 n 个权值{w1, w2, …, wn},构造具有 n 棵二 叉树的森林 F ={T1, T2, …, Tn },其中每棵二叉树 Ti 只有一个带权为 wi 的根结点, 其左、右子树均为空。 (2) 在 F 中选取两棵根结点的权值最小的二叉树, 作为 左、右子树构造一棵新的二叉树。置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。 (3)在 F 中删去这两棵二叉树, 把新的二叉树加入F。 (4)重复(2)和(3), 直到 F 中仅剩下一棵树为止。 ****************************霍夫曼编码***************************** 主要用途是实现数据压缩。由于赫夫曼树中没有度为1的节点,则一棵有n个叶子结点的赫夫曼树共有2n-1个结点,可以存储在一个大小为2n-1的一维数 组中。由于在构成赫夫曼树之后,为求编码需从叶子结点出发走一条从叶子到根的路径;而为译码需从根出发走一条从根到叶子的路径。则对每个结点而言,既须知双亲的信息,又需知孩子结点的信息。 2、本程序包含三个模块 1)主函数 Int main() { 先输入结点总数; 分别输入各个结点; 调用建立哈夫曼树函数; 调用编码函数读入建立的哈夫曼树进行编码 } 3、元素类型、结点类型和指针类型 typedef struct //定义新数据类型即结点结构

哈夫曼树源代码

#include #include #include #include #include typedef struct { float weight; int flag; int parent; int lchild; int rchild; }huffnode,*HuffmanTree; typedef struct { int bits[30]; int start; }huffcode; void numbers(int q) { int num=10000; int i,j,x1,x2,n,c,p;

float m1,m2; char ch,sh; FILE *fp; char filename[30]; printf("请给新文件命名:"); scanf("%s",filename); fp=fopen(filename,"w+"); n=10; float sum[10]={0}; for(i=1; i<=num; i++) { ch=rand()%10; sum[ch]++; printf("%c",ch+'0'); fprintf(fp,"%c",ch+'0');// fclose(fp); } fflush(stdin); printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!"); scanf("%c",&sh); system("cls");

printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n"); printf("\t\t* 接下来为你计算各个数字权值(请稍等)! *\n"); printf("\t\t********************************* ************"); Sleep(4*1000); fflush(stdin); //scanf("%c",&sh); system("cls"); printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!"); scanf("%c",&sh); system("cls"); printf("\t\t各数字权值如下:\n"); for(i=0;i

0023算法笔记——【贪心算法】哈夫曼编码问题

0023算法笔记——【贪心算法】哈夫曼编码问题 1、问题描述 哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。其压缩率通常在20%~90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。一个包含100,000个字符的文件,各字符出现频率不同,如下表所示。 有多种方式表示文件中的信息,若用0,1码表示字符的方法,即每个字符用唯一的一个0,1串表示。若采用定长编码表示,则需要3位表示一个字符,整个文件编码需要300,000位;若采用变长编码表示,给频率高的字符较短的编码;频率低的字符较长的编码,达到整体编码减少的目的,则整个文件编码需要(45×1+13×3+12×3+16×3+9×4+5×4)×1000=224,000位,由此可见,变长码比定长码方案好,总码长减小约25%。 前缀码:对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀。这种编码称为前缀码。编码的前缀性质可以使译码方法非常简单;例如001011101可以唯一的分解为0,0,101,1101,因而其译码为aabe。

译码过程需要方便的取出编码的前缀,因此需要表示前缀码的合适的数据结构。为此,可以用二叉树作为前缀码的数据结构:树叶表示给定字符;从树根到树叶的路径当作该字符的前缀码;代码中每一位的0或1分别作为指示某节点到左儿子或右儿子的“路标”。 从上图可以看出,表示最优前缀码的二叉树总是一棵完全二叉树,即树中任意节点都有2个儿子。图a表示定长编码方案不是最优的,其编码的二叉树不是一棵完全二叉树。在一般情况下,若C是编码字符集,表示其最优前缀码的二叉树中恰有|C|个叶子。每个叶子对应于字符集中的一个字符,该二叉树有|C|-1个内部节点。 给定编码字符集C及频率分布f,即C中任一字符c以频率f(c)在数据文件中出现。C的一个前缀码编码方案对应于一棵二叉树T。字符c在树T中的深度记为d T(c)。d T(c)也是字符c的前缀码长。则平均码长定义为:

哈夫曼编码算法实现完整版

实验三树的应用 一.实验题目: 树的应用——哈夫曼编码 二.实验内容: 利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。 要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。 三、程序源代码: #include #include #include #include typedef struct{ char data; int weight; int parent,lchild,rchild; }HTNode,*HuffmanTree; typedef char * * HuffmanCode; void Select(HuffmanTree &HT,int n,int m) {HuffmanTree p=HT; int tmp; for(int j=n+1;j<=m;j++) {int tag1,tag2,s1,s2; tag1=tag2=32767; for(int x=1;x<=j-1;x++) { if(p[x].parent==0&&p[x].weights2) //将选出的两个节点中的序号较小的始终赋给s1 { tmp=s1; s1=s2; s2=tmp;} p[s1].parent=j;

数据结构课设报告+哈夫曼编译器+C语言+源码

中南大学 数据结构课程设计报告 题目哈夫曼编译器 学生姓名孙毅 指导教师杨希 学院信息科学与工程学院 专业班级信息安全1401班 二○一六年十一月

目录 一、课程设计目的 (3) 二、课程设计的内容 (3) 2.1、问题描述 (3) 2.2、基本要求 (3) 三、问题描述,解决的方法 (3) 3.1从键盘读入字符集大小n , 以及n个字符和权值,建立哈夫曼树。 (3) 3.2利用已建好的哈夫曼树对文件正文进行编码,将结果存入相关文件中。5 3.3利用已建好的哈夫曼树将编码文件中的代码进行译码,结果存入文件中。 (6) 3.4输出代码文件,以紧凑格式显示。 (7) 3.5以直观的方式输出哈夫曼树,同时将此字符形式的哈夫曼树写入文件中。 (7) 四、程序模块功能,程序设计组成框图、流程图 (8) 4.1程序模块功能 (8) 4.2程序设计框图 (8) 4.3流程图 (9) 五、调试与测试。调试方法,测试结果的分析与讨论,遇到的主要问题及采取的解决措施。 (10) 5.1调试方面 (10) 5.2测试结果方面 (10) 六、测试结果,用几组测试数据进行测试算法设计的正确性 (10) 6.1第一组数据如下 (10) 6.2第二组测试数据如下: (14) 七、本次课程设计的心得体会 (16) 八、附录:源程序清单 (17)

一、课程设计目的 数据结构是计算机专业的核心课程,是计算机科学的算法理论基础和软件设计的技术基础,实践性强,课程设计是加强学生实践能力的一个重要手段。课程设计要求学生在完成程序设计的同时能够写出规范的设计报告,培养学生分析问题、解决问题,提高学生软件设计能力。 二、课程设计的内容 哈夫曼编译器 2.1、问题描述 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码。对于双向传输信息的信道,每端都需要一个完整的编译码系统。为这样的信息收发站编写哈夫曼编译系统。 2.2、基本要求 (1)从键盘读入字符集大小n , 以及n个字符和权值,建立哈夫曼树。 (2)利用已建好的哈夫曼树对文件正文进行编码,将结果存入相关文件中。 (3)利用已建好的哈夫曼树将编码文件中的代码进行译码,结果存入文件中。 (4)输出代码文件,以紧凑格式显示。 (5)以直观的方式输出哈夫曼树,同时将此字符形式的哈夫曼树写入文件中。 三、问题描述,解决的方法 3.1从键盘读入字符集大小n , 以及n个字符和权值,建立哈夫曼树。 a.首先设计一个结构体,成员有权值、左右儿子、以及字符本身,再设计一个输入函数,函数中要求输入字符集大小n,以及这n个字符和他们各自对应的权值。

哈夫曼编码_贪心算法

淮海工学院计算机工程学院实验报告书 课程名:《算法分析与设计》 题目:实验3 贪心算法 哈夫曼编码 班级:软件102班 学号:11003215 姓名:鹿迅

实验3 贪心算法 实验目的和要求 (1)了解前缀编码的概念,理解数据压缩的基本方法; (2)掌握最优子结构性质的证明方法; (3)掌握贪心法的设计思想并能熟练运用 (4)证明哈夫曼树满足最优子结构性质; (5)设计贪心算法求解哈夫曼编码方案; (6)设计测试数据,写出程序文档。 实验内容 设需要编码的字符集为{d 1, d 2, …, dn },它们出现的频率为 {w 1, w 2, …, wn },应用哈夫曼树构造最短的不等长编码方案。 实验环境 Turbo C 或VC++ 实验学时 2学时,必做实验 数据结构与算法 struct huffman { double weight; //用来存放各个结点的权值 int lchild,rchild,parent; //指向双亲、孩子结点的指针 }; 核心源代码 #include #include using namespace std; struct huffman { double weight; int lchild,rchild,parent; }; static int i1=0,i2=0; int Select(huffman huff[],int i) { ∑=j i k k a

int min=11000; int min1; for(int k=0;k

哈夫曼树的编写与输出

/******************************************/ /********* 哈夫曼树的编写与输出***********/ /******************************************/ /*用静态三叉链表实现哈夫曼树类型定义如下:*/ #define N 20 #define M 2*N-1 typedef struct { int weight; int parent; int LChild; int RChild; } HTNode,HuffmanTree[M+1]; /*select函数主体程序代码*/ void select(HuffmanTree ht,int j,& s1,& s2 ) { int i,k; int n=0; HuffmanTree rt; for(k=0;k<=j;k++) { if(ht[k].parent ==0) { rt[k]=ht[k]; n=n+1; } } for(k=0;k

int m; m=2*n-1; for(i=n+1;i<=m;i++) { ht[i]={0,0,0,0}; } /*--------初始化完毕,对应算法步鄹(1)---------*/ for(i=n+1;i<=m;i++) { int s1,s2; select(ht,i-1,&s1,$s2); ht[i].weight=ht[s1].weight +ht[s2].weight ; ht[s1].parent=i;ht[s2].parent=i; ht[i].LChild=s1;ht[i].RChild=s2; } }

哈夫曼树建立、哈夫曼编码算法的实现

#include /*2009.10.25白鹿原*/ #include /*哈夫曼树建立、哈夫曼编码算法的实现*/ #include 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) {

哈夫曼树与文件解压压缩C言代码

1.问题描述 哈弗曼树的编码与译码 —功能:实现对任何类型文件的压缩与解码 —输入:源文件,压缩文件 —输出:解码正确性判定,统计压缩率、编码与解码速度 —要求:使用边编码边统计符号概率的方法(自适应Huffman编码)和事先统计概率的方法(静态Huffman编码) 2.1程序清单 程序书签: 1.main函数 2.压缩函数 3.select函数 4.encode函数 5.解压函数 #include #include #include #include #include struct node{

long weight; //权值 unsigned char ch;//字符 int parent,lchild,rchild; char code[256];//编码的位数最多为256位int CodeLength;//编码长度 }hfmnode[512]; void compress(); void uncompress(); //主函数 void main() { int choice; printf("请选择1~3:\n"); printf("1.压缩文件\n"); printf("2.解压文件\n"); printf("3.退出!\n"); scanf("%d",&choice); if(choice==1)compress(); else if(choice==2)uncompress(); else if(choice==3)return; else printf("输入错误!"); }

4+四+贪心算法+习题参考答案

第四章作业 部分参考答案 1. 设有n 个顾客同时等待一项服务。顾客i 需要的服务时间为n i t i ≤≤1,。应该如何安排n 个顾客的服务次序才能使总的等待时间达到最小?总的等待时间是各顾客等待服务的时间的总和。试给出你的做法的理由(证明)。 策略: 对 1i t i n ≤≤进行排序,,21n i i i t t t ≤≤≤ 然后按照递增顺序依次服务12,,...,n i i i 即可。 解析:设得到服务的顾客的顺序为12,,...,n j j j ,则总等待时间为 ,2)2()1(1221--+++-+-=n n j j j j t t t n t n T 则在总等待时间T 中1j t 的权重最大,jn t 的权重最小。故让所需时间少的顾客先得到服务可以减少总等待时间。 证明:设,21n i i i t t t ≤≤≤ ,下证明当按照不减顺序依次服务时,为最优策略。 记按照n i i i 21次序服务时,等待时间为T ,下证明任意互换两者的次序,T 都不减。即假设互换j i ,)(j i <两位顾客的次序,互换后等待总时间为T ~ ,则有.~ T T ≥ 由于 ,2)2()1(1221--+++-+-=n n i i i i t t t n t n T ,2)()()2()1(1221--+++-++-++-+-=n n j i i i i i i i t t t j n t i n t n t n T ,2)()()2()1(~ 1221--+++-++-++-+-=n n i j i i i i i i t t t j n t i n t n t n T 则有 .0))((~ ≥--=-i j i i t t i j T T 同理可证其它次序,都可以由n i i i 21经过有限次两两调换顺序后得到,而每次交换,总时间不减,从而n i i i 21为最优策略。

实验四 哈夫曼树与哈夫曼编码

实验四哈夫曼树与哈夫曼编码 一、实验内容 [问题描述] 已知n个字符在原文中出现的频率,求它们的哈夫曼编码。[基本要求] 1. 初始化:从键盘读入n个字符,以及它们的权值,建立Huffman 树。(具体算法可参见教材P147的算法6.12) 2. 编码:根据建立的Huffman树,求每个字符的Huffman 编码。 对给定的待编码字符序列进行编码。 二、概要设计 算法设计: 要是实现哈夫曼树的操作,首先创建一个哈夫曼树,在创建哈夫曼树的时候,对哈夫曼树的叶子和非叶子结点进行初始化,而在建立哈夫曼树时,最难的该是选择权值最小的两个顶点,然后两个结点的权值和作为新的权值,再选择两个权值最小的作为新的两个结点创建一个小的二叉树的子树;创建哈夫曼树后,进行编码,在编码过程中,先找到根,然后遍历,左孩子用0标记,右孩子用1标记,最后将编码好的哈夫曼树进行输出,就可以知道哈夫曼树的编码了。 流程图:

算法:

模块: 在分析了实验要求和算法分析之后,将程序分为四个功能函数,分别如下: 首先建立一个哈夫曼树和哈夫曼编码的存储表示: typedef struct { int weight; int parent,lchild,rchild; char elem; }HTNode,*HuffmanTree;//动态分配数组存储赫夫曼树 typedef char **HuffmanCode;//动态分配数组存储赫夫曼编码表CrtHuffmanTree(HuffmanTree *ht , int *w, int n):w存放n个字符的权值,构造哈夫曼树HT。先将叶子初始化,再将非叶子结点初始化,然后构造哈夫曼树。 构造哈夫曼树: for(i=n+1;i<=m;++i) {//在HT[1……i]选择parent为0且weight最小的两个Select(HT,i-1,&s1,&s2);

哈夫曼编解码 完整c程序代码

1)内容: 利用 Huffman 编码进行通信可以大大提高信道的利用率,缩短信息传输时间,降低 传输成本。但是,这要求在发送端通过一个编码系统对待传数据进行预先编码,在 接收端进行解码。对于双工信道(即可以双向传输信息的信道),每端都需要一个 完整的编/解码系统。 2)要求: 一个完整的huffman编解码系统应该具有以下功能: 初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建 立Huffman 树,并将它存入hfmTree 中。 编码(Encoding)。利用已经建好的Huffman树(如果不在内存,则应从文件hfmTree 中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件hfmTree中读取),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 解码(Decoding)。利用已经建立好的Huffman树将文件CodeFile中的代码进行解码, 结果存入TextFile中。 打印代码文件(Print)。将文件CodeFile以紧凑的格式显示在终端上,每行 50 个 代码。同时将此字符形式的编码文件写入文件CodePrint中。 打印Huffman树(Tree Printing)。将已经在内存中的Huffman树以直观的形式(树或者凹入的形式)显示在终端上,同时将此字符形式的Huffman 树写入文件TreePrint中。 3) 测试数据: 用下表给出的字符集和频度的实际统计数据建立Huffman树,并对以下报文进行编码和译码:“THIS PROGRAM IS MY FAVORITE”。 完整代码如下: #include #include #include #define N 100 int *w; char *c,stack[N],code[N][N]; int s1,s2; typedef struct HuffmanTree { int weight; int parent; int lchild; int rchild; }HuffmanTree,*Huff; void menu(void); void Select(struct HuffmanTree HT[],int i);

哈夫曼树及编码综合实验报告

《用哈夫曼编码实现文件压缩》 实验报告 课程名称数据结构B 实验学期 2017 至 2018 学年第一学期学生所在院部计算机学院 年级 2016 专业班级信管B162 学生姓名学号 成绩评定: 1、工作量: A(),B(),C(),D(),F( ) 2、难易度:A(),B(),C(),D(),F( ) 3、答辩情况: 基本操作:A(),B(),C(),D(),F( ) 代码理解:A(),B(),C(),D(),F( ) 4、报告规范度:A(),B(),C(),D(),F( ) 5、学习态度:A(),B(),C(),D(),F( )总评成绩:_________________________________ 指导教师: 兰芸

用哈夫曼编码实现文件压缩 1、了解文件的概念。 2、掌握线性链表的插入、删除等算法。 3、掌握Huffman树的概念及构造方法。 4、掌握二叉树的存储结构及遍历算法。 5、利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。 微型计算机、Windows 7操作系统、Visual C++6.0软件 输入的字符创建Huffman树,并输出各字符对应的哈夫曼编码。 五.系统设计 输入字符的个数和各个字符以及权值,将每个字符的出现频率作为叶子结点构建Huffman树,规定哈夫曼树的左分支为0,右分支为1,则从根结点到每个叶子结点所经过的分支对应的0和1组成的序列便为该结点对应字符的哈夫曼编码。 流程图如下 1.输入哈夫曼字数及相应权值

相应代码 int main() { HuffmanTree HTree; HuffmanCode HCode; int *w, i; int n,wei; //编码个数及权值 printf("请输入需要哈夫曼编码的字符个数:"); scanf("%d",&n); w=(int*)malloc((n+1)*sizeof(int)); for(i=1; i<=n;i++) { printf("请输入第%d字符的权值:",i); fflush(stdin); scanf("%d",&wei); w[i]=wei; } HuffmanCoding(&HTree,&HCode,w,n); return 1; } 2.输出HT初态(每个字符的权值)

相关文档
最新文档