1、资料查阅与讨论(1天)系统分析(2天)系统的开发与测试(5天)编写课程设计说明书和验收(2天)五、评分标准1. 根据平时上机考勤、表现和进度,教师将每天点名和检查2. 根据课程设计完成情况,必须有可运行的软件。3. 根据课程设计报告的质量,如有雷同,则所有雷同的所有人均判为不及格。4. 根据答辩的情况,应能够以清晰的思路和准确、简练的语言叙述自己的设计和回答教师的提问六、建议参考资料1数据结构 (C语言版)严蔚敏、吴伟民 主编 清华大学出版社 2004.112数据结构课程设计案例精编(用C/C+描述),李建学 等 编著,清华大学出版社 2007.23.数据结构:用面向对象方法与C+语言描述,殷
2、人昆 主编,清华大学出版社 2007目录第一章 需求分析 4第二章 总体设计 5第三章 抽象数据类型定义 63.1 LinkList抽象数据类型的设计 63.2 HuffmanTree抽象数据的设计 6第四章 详细设计.7第五章 测试 8第六章 总结 9附录:程序代码 10第一章 需求分析哈夫曼编码是一种编码方式,以哈夫曼树即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。哈弗曼编码使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,
3、这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。赫夫曼编码的应用很广泛,利用赫夫曼树求得的用于通信的二进制编码称为赫夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是赫夫曼编码。哈弗曼译码输入字符串可以把它编译成二进制代码,输入二进制代码时可以编译成字符串。第二章 总体设计(1) 输入一个字符串用结构体链表存储字符串中出现的不同字符及其出现的次数。(2) 定义赫夫曼数的结点结构体,把不同的字符及其在字符串中出现的次数作为叶子结
4、点的元素及其权值,统计叶子结点的个数n,开辟可以存储2*n个结点的顺序表,来赫夫曼树的各个结点,然后按照一定的规则构造赫夫曼树。(3) 开辟一个可以存储叶子结点元素及指向存储其赫夫曼编码链表的指针的顺序表,然后从叶子结点开始向上访问,是左孩子的把“0”接进链表是右孩子的把“1”接进链表,直到根结点,然后把叶子结点的元素及存储其赫夫曼链表的头指针读入顺序表,直到把所有的叶子结点的元素及指向存储其赫夫曼编码链表的头指针读入顺序表,这样得到的赫夫曼编码是倒序的。(4) 从存储其叶子结点及指向存储其赫夫曼编码链表头指针的顺序表表头开始顺序访问各元素,在输出其赫夫曼编码之前,把链表中的编码顺序读入到等长
5、的栈中,然后编码出栈就会得到顺序的赫夫曼编码,直到把所有的叶子结点都访问到。(5) 用一个字符型的指针指向字符串的第一个字符,从存储叶子结点元素及指向存储其赫夫曼编码链表的头指针的顺序表表头开始访问顺序表中的各元素,直到找到叶子结点的元素和当前字符相等就结束访输出赫夫曼编码,直到输出字符串的最后一个字符的赫夫曼编码,这样就得到输入字符串的赫夫曼编码。第三章 抽象数据类型定义3.1 LinkList抽象数据类型的设计ADT LinkList数据对象:D = ai | aiElemSet,i = 1,2,n,n0 数据关系:R1= | ai-1,aiD,i = 2,n 基本操作:ListEmpty
6、( L )初始条件:线性表L已存在。操作结果:若L表为空表,则返回TRUE,否则返回FALSE。ListLength( L )返回L中数据元素个数。GetElem( L , i , &e )1iListLength( L )。用e返回L中第i个数据元素的值。ListTraverse( L , visit( ) )依次对L的每个数据元素调用函数visit( )。一旦visit()失败,则操作失败。ADT LinkList3.2 HuffmanTree抽象数据的设计 typedef struct /赫夫曼树的结构体 char ch; int weight; /权值 int parent,lchil
7、d,rchild;htnode,*hfmtree;第四章 详细设计第五章 测试图表 1 5.1图5.1为 哈夫曼编码与译码。第六章 总结通过本次实验首先学习了霍夫曼树及其编码,接着分析写出了建立霍夫曼树和计算霍夫曼编码算法的代码,在huffman编码当中虽出现许多错误但通过了进一步的学习都可以学习改正,基本上可以实现Huffman编码算法的实现与编程应用。两个星期的不懈努力,哈夫曼编译码系统课程设计顺利结束了,在这个过程中我收获了不少,同时也了解自己在某些方面做的还不够。在此,感谢两星期来一直指导我们的班主任和那些为我解决设计过程中遇到的难题的同学们,谢谢大家!今后我将继续努力,争取编出一套完
8、整的哈夫曼编译码系统。 程序代码#include string/系统自带的字符串库函数stdlib.husing namespace std;struct Node char data; / 节点数据域为字符型 Node *next; Node() next = NULL; Node(char item, Node *link = NULL) data = item; next = link;class LinkList/仅保留几个用得到的成员函数protected: Node *head; Node *curPtr; int count,curPosition; Node *GetElemP
9、tr(int position); / 返回指向第position个结点的指针public: LinkList(); int Length() const; bool Empty() const; void Traverse() ; void Insert(int position, const char &e); char GetElem(int position) ;Node * LinkList:GetElemPtr(int position) if (curPosition position) curPosition = 0; curPtr = head; for (; curPosi
10、tion next; return curPtr;char LinkList:GetElem(int position) Node *tmpPtr; tmpPtr = GetElemPtr(position); char e = tmpPtr-data; return e;LinkList:LinkList() head = new Node; / 构造头指针,带表头结点的链表 curPosition =0; count = 0;int LinkList:Length() const return count;bool LinkList:Empty() const return head-ne
11、xt = NULL;void LinkList:Traverse() for (Node *tmpPtr = head- tmpPtr != NULL; tmpPtr = tmpPtr-next) coutdata);Insert(int position, const char &e) tmpPtr = GetElemPtr(position - 1); Node *newPtr; newPtr = new Node(e, tmpPtr-next); tmpPtr-next = newPtr; curPosition = position; curPtr = newPtr; count+;/
12、 哈夫曼树结点类struct HuffmanTreeNode unsigned int parent, leftChild, rightChild; / 双亲,左右孩子域 HuffmanTreeNode(); HuffmanTreeNode(int w, int p = 0, int lChild = 0, int rChild = 0);HuffmanTreeNode:HuffmanTreeNode() parent = leftChild = rightChild = 0;HuffmanTreeNode(int w, int p, int lChild, int rChild) / 右孩子
13、 weight = w; / 权 parent = p; / 双亲 leftChild = lChild; / 左孩子 rightChild = rChild; / 右孩子class HuffmanTree/ HuffmanTreeNode *nodes; / 存储结点信息,nodes0未用 char *LeafChars; / 叶结点字符信息,LeafChars0未用 string *LeafCharCodes; / 叶结点字符编码信息,LeafCharCodes0未用 int curPos; / 译码时从根结点到叶结点路径的当前结点 int num; / 叶结点个数/ 辅助函数: void
14、 Select(int cur, int &r1, int &r2); / nodes1 cur中选择双亲为0,权值最小的两个结点r1,r2 void CreatHuffmanTree(char ch, int w, int n); public: HuffmanTree(char ch, int w, int n); / 由字符,权值和字符个数构造哈夫曼树 virtual HuffmanTree(); / 析构函数 string Encode(char ch); / 编码 LinkList Decode(string strCode); / 译码void HuffmanTree:Select
15、(int cur, int &r2) r1 = r2 = 0; / 0表示空结点 for (int pos = 1; pos = cur; pos+) if (nodespos.parent != 0) continue; / 只处理双亲为0的结点 if (r1 = 0) r1 = pos; else if (r2 = 0) r2 = pos; else if (nodespos.weight nodesr1.weight) nodesr2.weight)CreatHuffmanTree(char ch, int w, int n) num = n; int m = 2 * n - 1; /
16、结点个数 nodes = new HuffmanTreeNodem + 1; / nodes0未用 LeafChars = new charn + 1; / LeafChars0未用 LeafCharCodes = new stringn + 1; / LeafCharCodes0未用 int pos; / 临时变量 for (pos = 1;= n; / 存储叶结点信息 nodespos.weight = wpos - 1; / 权值 LeafCharspos = chpos - 1; / 字符 for (pos = n + 1;= m; / 建立哈夫曼树 int r1, r2; Selec
17、t(pos - 1, r1, r2); nodesr1.parent = nodesr2.parent = pos; / r1,r2双亲为pos nodespos.leftChild = r1; / r1为pos的左孩子 nodespos.rightChild = r2; / r2为pos的右孩子 nodespos.weight = nodesr1.weight + nodesr2.weight;/pos的权为r1,r2的权值之和 / 求n个叶结点字符的编码 LinkList charCode; / 暂存叶结点字符编码信息 for (unsigned int child = pos, pare
18、nt = nodeschild.parent; parent != 0; child = parent, parent = nodeschild.parent) if (nodesparent.leftChild = child) charCode.Insert(1,0); else charCode.Insert(1,1; for(int i=1;in; ch=new charn; w=new intn;请输入字符集中的字符: for(i=0;chi;请输入字符集中的字符的权值:wi; HuffmanTree hmTree(ch, w, n); string strText,strCode;
19、请输入要编码的字符串strText; cout 文本串 strText.c_str()编码为: for (int pos1 = 0; pos1 strText.length(); pos1+) string strTmp = hmTree.Encode(strTextpos1); strTmp.c_str(); endl; int pos = 0;chi的编码为: string strTmp = hmTree.Encode(chpos); strTmp.c_str() pos+; system(PAUSE请输入要译码的二进制串strCode;编码串 strCode.c_str()译码为: LinkList lkText = hmTree.Decode(strCode); lkText.Traverse(); return 0;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1