哈夫曼树算法伪代码

哈夫曼树算法伪代码

1. 数组huffTree初始化,所有元素结点的双亲、左右孩子都置为-1;

2. 数组huffTree的前n个元素的权值置给定权值w[n];

3. 进行n-1次合并

3.1 在二叉树集合中选取两个权值最小的根结点,其下标分别为i1, i2;

3.2 将二叉树i1、i2合并为一棵新的二叉树k;

中衡算法分析与【设计明细】-实验二-哈夫曼编码

昆明理工大学信息工程与自动化学院学生实验报告 (201 —201 学年第一学期) 课程名称:算法设计与分析开课实验室:年月日 一、上机目的及内容 1.上机内容 设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。 2.上机目的 (1)了解前缀编码的概念,理解数据压缩的基本方法; (2)掌握最优子结构性质的证明方法; (3)掌握贪心法的设计思想并能熟练运用。 二、实验原理及基本技术路线图(方框原理图或程序流程图) (1)证明哈夫曼树满足最优子结构性质; (2)设计贪心算法求解哈夫曼编码方案; (3)设计测试数据,写出程序文档。 数据结构与算法: typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码 typedef struct { unsigned int weight; //用来存放各个结点的权值 unsigned int parent,LChild,RChild; //指向双亲、孩子结点的指针 } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 程序流程图:

三、所用仪器、材料(设备名称、型号、规格等或使用软件) 1台PC及VISUAL C++6.0软件

四、实验方法、步骤(或:程序代码或操作过程) 程序代码: #include #include #include typedef struct { unsigned int weight; unsigned int parent,LChild,RChild; } HTNode, *HuffmanTree; //动态分配数组,存储哈夫曼树 typedef char *HuffmanCode; //动态分配数组,存储哈夫曼编码 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++) { if((*ht)[i].parent==0 && i!=(*s1)) { min=i; break; } } for(i=1; i<=n; i++) { if((*ht)[i].parent==0 && i!=(*s1)) { if((*ht)[i].weight<(*ht)[min].weight)

贪心算法构造哈夫曼树

软件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.求每个字符的哈夫曼编码并显示。

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

实验四 哈夫曼编码的贪心算法设计(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 编码表节点结构:

数据结构课程设计哈夫曼编码-2

数据结构课程设计哈夫曼编码-2

《数据结构与算法》课程设计 目录 一、前言 1.摘要 2.《数据结构与算法》课程设计任务书 二、实验目的 三、题目--赫夫曼编码/译码器 1.问题描述 2.基本要求 3.测试要求 4.实现提示 四、需求分析--具体要求 五、概要设计 六、程序说明 七、详细设计 八、实验心得与体会

前言 1.摘要 随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。 算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。 《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。 学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。

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

实验三树的应用 一.实验题目: 树的应用——哈夫曼编码 二.实验内容: 利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。 要求:从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。 三、程序源代码: #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;

哈夫曼编码步骤

哈夫曼编码步骤: 一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F= {T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。) 二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。 三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。 四、重复二和三两步,直到集合F中只有一棵二叉树为止。 /*------------------------------------------------------------------------- * Name: 哈夫曼编码源代码。 * Date: 2011.04.16 * Author: Jeffrey Hill+Jezze(解码部分) * 在Win-TC 下测试通过 * 实现过程:着先通过HuffmanTree() 函数构造哈夫曼树,然后在主函数main()中 * 自底向上开始(也就是从数组序号为零的结点开始)向上层层判断,若在 * 父结点左侧,则置码为0,若在右侧,则置码为1。最后输出生成的编码。*------------------------------------------------------------------------*/ #include #include #define MAXBIT 100 #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; int value;} HNodeType; /* 结点结构体*/ /* 构造一颗哈夫曼树*/ void HuffmanTree (HNodeType HuffNode[MAXNODE], int n){ /* i、j:循环变量,m1、m2:构造哈夫曼树不同过程中两个最小权值结点的权值,x1、x2:构造哈夫曼树不同过程中两个最小权值结点在数组中的序号。*/ int i, j, m1, m2, x1, x2; /* 初始化存放哈夫曼树数组HuffNode[] 中的结点*/ for (i=0; i<2*n-1; 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 /*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) {

哈夫曼编码_贪心算法

淮海工学院计算机工程学院实验报告书 课程名:《算法分析与设计》 题目:实验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; } }

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为最优策略。

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

《用哈夫曼编码实现文件压缩》 实验报告 课程名称数据结构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初态(每个字符的权值)

哈夫曼编码的JAVA实现课程设计

哈夫曼编码的JAVA实现课程设计 目录 摘要 (2) 一、问题综述 (2) 二、求解方法介绍 (3) 三、实验步骤及结果分析 (4) 四、程序设计源代码 (5) 参考文献 (8)

摘要 利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本,试用java语言设计一个哈夫曼编码系统。通过本课程设计,应使学生掌握哈夫曼编码的特点、储存方法和基本原理,培养学生利用java语言正确编写程序及调试程序的能力,运用数据结构知识解决实际问题的能力。 关键字:哈夫曼编码JA V A语言类方法 一、问题综述 1 哈夫曼编码的算法思想 哈夫曼编码也称前缀编码,它是根据每个字符出现的频率而进行编码的,要求任一字符的编码都不是其它任意字符编码的前缀且字符编码的总长度为最短。它主要应用于通信及数据的传送以及对信息的压缩处理等方面。哈夫曼编码的基础是依据字符出现的频率值而构造一棵哈夫曼树,从而实现最短的编码表示最常用的数据块或出现频率最高的数据,具体的方法是: 1.1 建立哈夫曼树 把N 个字符出现的频率值作为字符的权值,然后依据下列步骤建立哈夫曼树。 1.1.1 由N 个权值分别作N 棵树的根结点而形成一个森林。 1.1.2 从中选择两棵根值最小的树T1 和T2 组成一棵以结点T 为根结点的增长树,根结点T = T1 + T2 ,即新树的根值为原来两棵树的根值之和,而T1 和T2 分别为增长树的左右子树。 1.1.3 把这棵新树T 加入到森林中,把原来的两棵树T1 和T2 从森林中删除。 1.1.4 重复1.1.2~1.1.3 步,直到合并成一棵树为止。 1.2 生成各字符的哈夫曼编码 在上面形成的哈夫曼树中,各个字符的权值结点都是叶子结点,从叶子结点开始向根搜索,如果是双亲的左分支,则用“0”标记,右分支用“1”标记,从叶子结点到根结点所经过的分支编码“0”、“1”的组合序列就是各字符的哈夫曼编码。 2 构造哈夫曼树的算法 1)对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,..., Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。 2)在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。 3)从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F 中。

数字图像实验 哈夫曼编码的方法和实现1234

实验八哈夫曼编码的方法和实现 一、实验目的 1.掌握哈夫曼编码的基本理论和算法流程; 2. 用VC++6.0编程实现图像的哈夫曼编码。 二、实验内容 1.画出哈夫曼编码的算法流程; 2.用VC++6.0编程实现哈夫曼编码。 三、实验步骤 (1)启动VC++6.0,打开Dip工程。 (2)在菜单栏→insert→resouce→dialog→new,在对话框模版的非控制区点击鼠标右键,在弹出的对话框中选properties,设置为ID:IDD_DLG_Huffman,C标题:哈夫曼编码表。 (3)在弹出的对话框中,添加如下的按钮等控件: (4)在ResourceView栏中→Menu→选IDR_DIPTYPE ,如图 在图像编码菜单栏下空的一栏中,右键鼠标,

在弹出的对话框中选属性properties,在弹出的对话框中,进行如下的设置 (5)右击哈夫曼编码表菜单栏,在建立的类向导中进行如下设置 (6)在DipDoc.cpp中找到void CDipDoc::OnCodeHuffman()添加如下代码void CDipDoc::OnCodeHuffman() { int imgSize; imgSize = m_pDibObject->GetWidth()*m_pDibObject->GetHeight(); //在点处理CPointPro类中创建用来绘制直方图的数据 CPointPro PointOperation(m_pDibObject ); int *pHistogram = PointOperation.GetHistogram(); //生成一个对话框CHistDlg类的实例 CDlgHuffman HuffmanDlg;

数据结构实验三题目二_哈夫曼树

2008级数据结构实验报告 实验名称:实验三树 学生姓名: 班级: 班内序号: 学号: 日期: 20013年11月26日 1.实验要求 实验目的 通过选择下面两个题目之一进行实现,掌握如下内容: 掌握二叉树基本操作的实现方法 了解赫夫曼树的思想和相关概念 学习使用二叉树解决实际问题的能力 实验内容 利用二叉树结构实现赫夫曼编/解码器。 基本要求: 1.初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并 建立赫夫曼树 2.建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码 输出。 3.编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。 4.译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结 果。 5.打印(Print):以直观的方式打印赫夫曼树(选作) 6.计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。 2. 程序分析 哈夫曼树结点的储存结构除了二叉树所有的双亲域parents,左子树域lchild,右子树域rchild。还需要有字符域word,权重域weight,编码域code。其中由于编码是一串由0和1组成的字符串,所以code是一个字符数组。 进行哈夫曼编码首先要对用户输入的信息进行统计,将每个字符作为哈夫曼树的叶子结点。统计每个字符出现的次数(频度)作为叶子的权重,统计次数可以根据每个字符不同的ASCII 码。并根据叶子结点的权重建立一个哈夫曼树。 建立每个叶子的编码从根结点开始,规定通往左子树路径记为0,通往右子树路径记为 1.由于编码要求从根结点开始,所以需要前序遍历哈夫曼树,故编码过程是以前序遍历二叉树

哈夫曼编码的方法

1.哈夫曼编码的方法 编码过程如下: (1) 将信源符号按概率递减顺序排列; (2) 把两个最小的概率加起来, 作为新符号的概率; (3) 重复步骤(1) 、(2), 直到概率和达到1 为止; (4) 在每次合并消息时,将被合并的消息赋以1和0或0和1; (5) 寻找从每个信源符号到概率为1处的路径,记录下路径上的1和0; (6) 对每个符号写出"1"、"0"序列(从码数的根到终节点)。 2.哈夫曼编码的特点 ①哈夫曼方法构造出来的码不是唯一的。 原因 ·在给两个分支赋值时, 可以是左支( 或上支) 为0, 也可以是右支( 或下支) 为0, 造成编码的不唯一。 ·当两个消息的概率相等时, 谁前谁后也是随机的, 构造出来的码字就不是唯一的。 ②哈夫曼编码码字字长参差不齐, 因此硬件实现起来不大方便。 ③哈夫曼编码对不同的信源的编码效率是不同的。 ·当信源概率是2 的负幂时, 哈夫曼码的编码效率达到100%; ·当信源概率相等时, 其编码效率最低。 ·只有在概率分布很不均匀时, 哈夫曼编码才会收到显著的效果, 而在信源分布均匀的情况下, 一般不使用哈夫曼编码。 ④对信源进行哈夫曼编码后, 形成了一个哈夫曼编码表。解码时, 必须参照这一哈夫编码表才能正确译码。 ·在信源的存储与传输过程中必须首先存储或传输这一哈夫曼编码表在实际计算压缩效果时, 必须考虑哈夫曼编码表占有的比特数。在某些应用场合, 信源概率服从于某一分布或存在一定规律

使用缺省的哈夫曼编码表有

解:为了进行哈夫曼编码, 先把这组数据由大到小排列, 再按上方法处理 (1)将信源符号按概率递减顺序排列。 (2)首先将概率最小的两个符号的概率相加,合成一个新的数值。 (3)把合成的数值看成是一个新的组合符号概率,重复上述操作,直到剩下最后两个符号。 5.4.2 Shannon-Famo编码 Shannon-Famo(S-F) 编码方法与Huffman 的编码方法略有区别, 但有时也能编 出最佳码。 1.S-F码主要准则 符合即时码条件; 在码字中,1 和0 是独立的, 而且是( 或差不多是)等概率的。 这样的准则一方面能保证无需用间隔区分码字,同时又保证每一位码字几乎有 1位的信息量。 2.S-F码的编码过程 信源符号按概率递减顺序排列; 把符号集分成两个子集, 每个子集的概率和相等或近似相等;

贪心算法概论

贪心算法概论 贪心算法一般来说是解决“最优问题”,具有编程简单、运行效率高、空间 复杂度低等特点。是信息学竞赛中的一个有为武器,受到广大同学们的青睐。本 讲就贪心算法的特点作些概念上的总结。 一、贪心算法与简单枚举和动态规划的运行方式比较 贪心算法一般是求“最优解”这类问题的。最优解问题可描述为:有n个输入,它的解是由这n 个输入的某个子集组成,并且这个子集必须满足事先给定的条 件。这个条件称为约束条件。而把满足约束条件的子集称为该问题的可行解。这 些可行解可能有多个。为了衡量可行解的优劣,事先给了一个关于可行解的函数,称为目标函数。目标函数最大(或最小)的可行解,称为最优解。 a)求“最优解”最原始的方法为搜索枚举方案法(一般为回溯法)。 除了极简单的问题,一般用深度优先搜索或宽度优先搜索。通常优化方法为利用约束条件进行可行性判断剪枝;或利用目标函数下界(或上界),根据当前最 优解进行分枝定界。 b)其次现今竞赛中用的比较普遍的动态规划(需要满足阶段无后效性原则)。 动态规划主要是利用最最优子问题的确定性,从后向前(即从小规模向大规模)得到当前最优策略,从而避免了重复的搜索。 举例说明:求多段图的最短路径。

在图(1)中,我们省略了各线段的长度。 如果用回溯法,搜索树大致如下: 显然,上面的搜索有大量重复性工作。比如节点8、9、10到11的最短路分别被调用了9次,从节点5、6、7到节点11也分别搜索了3次。 如果先算出节点8、9、10到11的最短路,由于它与前面的点无关,因此最优值确定下来,再用它们求定节点5、6、7 到节点11 的最短路径。同理,再用节 点5、6、7 的最优值,来求节点2、3、4 优值。最后从节点2、3、4 推出1 到 11的最优值。显然复杂度大为降低。 当然,如果本题把简单搜索改为搜索+记忆化的方法,则就是得能动态规划的原理,本质上就是动态规划,只是实现的方法不同与传统的表格操作法。搜索+记忆化算法有其特有的特点,以后再讨论。 c)贪心算法则不同,它不是建立在枚举方案的基础上的。它从前向后,根据当前情况,“贪心地”决定出下一步,从而一步一步直接走下去,最终得到解。 假如上面的例子中,我们定下这样的贪心策略:节点号k%3= =1。则有图3:

相关文档
最新文档