数据结构实验十二 哈夫曼树及编码

简介: 数据结构实验十二 哈夫曼树及编码

一.实验目的

练习树和哈夫曼树的有关操作,和各个算法程序,理解哈夫曼树的编码和译码 。

二.实验内容

1. 根据给出的字符以及这些字符的使用频率构建哈夫曼树。

2. 根据哈夫曼树对字符进行哈夫曼编码,并保存这些编码。

三.实验步骤

1. 建立哈夫曼树的存储结构和哈夫曼编码的存储结构。

2. 建立哈夫曼树的函数;

3. 哈夫曼编码的函数;

4. 哈夫曼编码的解码函数

1. #include<iostream>
2. #include <cstring>
3. using namespace std;
4. typedef struct
5. {
6.  int weight;
7.  int parent,lchild,rchild;
8. }HTNode,*HuffmanTree;
9. typedef char **HuffmanCode;
10. 
11. void Select(HuffmanTree HT,int len,int &s1,int &s2)
12. {
13.   int i,min1=0x3f3f3f3f,min2=0x3f3f3f3f;//先赋予最大值
14.   for(i=1;i<=len;i++)
15.   {
16.     if(HT[i].weight<min1&&HT[i].parent==0)
17.     {
18.       min1=HT[i].weight;
19.       s1=i;
20.     } 
21.   }
22.   int temp=HT[s1].weight;//将原值存放起来,然后先赋予最大值,防止s1被重复选择
23.   HT[s1].weight=0x3f3f3f3f;
24.   for(i=1;i<=len;i++)
25.   {
26.     if(HT[i].weight<min2&&HT[i].parent==0)
27.     {
28.       min2=HT[i].weight;
29.       s2=i;
30.     }
31.   }
32.   HT[s1].weight=temp;//恢复原来的值
33. }
34. 
35. //用算法5.10构造赫夫曼树
36. void CreatHuffmanTree(HuffmanTree &HT,int n)
37. {
38.   //构造赫夫曼树HT
39.   int m,s1,s2,i;
40.   if(n<=1) return;
41.   m=2*n-1;
42.   HT=new HTNode[m+1];     //0号单元未用,所以需要动态分配m+1个单元,HT[m]表示根结点   
43.   for(i=1;i<=m;++i)         //将1~m号单元中的双亲、左孩子,右孩子的下标都初始化为0
44.      { HT[i].parent=0;  HT[i].lchild=0;  HT[i].rchild=0; }
45.   cout<<"请输入叶子结点的权值:\n";
46.   for(i=1;i<=n;++i)         //输入前n个单元中叶子结点的权值  
47.     cin>>HT[i].weight;  
48.   /*――――――――――初始化工作结束,下面开始创建赫夫曼树――――――――――*/
49.   for(i=n+1;i<=m;++i) 
50.   {   //通过n-1次的选择、删除、合并来创建赫夫曼树
51.     Select(HT,i-1,s1,s2);
52.     //在HT[k](1≤k≤i-1)中选择两个其双亲域为0且权值最小的结点,
53.     // 并返回它们在HT中的序号s1和s2
54.     HT[s1].parent=i;  
55.     HT[s2].parent=i;   
56.     //得到新结点i,从森林中删除s1,s2,将s1和s2的双亲域由0改为i
57.     HT[i].lchild=s1;   
58.     HT[i].rchild=s2 ;             //s1,s2分别作为i的左右孩子
59.     HT[i].weight=HT[s1].weight+HT[s2].weight;   //i 的权值为左右孩子权值之和
60.   }                       //for
61. } 
62.                         // CreatHuffmanTree
63. void CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
64. {
65.   //从叶子到根逆向求每个字符的赫夫曼编码,存储在编码表HC中
66.   int i,start,c,f;
67.   HC=new char*[n+1];                    //分配n个字符编码的头指针矢量
68.   char *cd=new char[n];             //分配临时存放编码的动态数组空间
69.   cd[n-1]='\0';                               //编码结束符
70.   for(i=1;i<=n;++i)
71.   {                               //逐个字符求赫夫曼编码
72.     start=n-1;                //start开始时指向最后,即编码结束符位置
73.     c=i; 
74.     f=HT[i].parent;                       //f指向结点c的双亲结点
75.     while(f!=0)
76.     {                          //从叶子结点开始向上回溯,直到根结点
77.       --start;                   //回溯一次start向前指一个位置
78.       if(HT[f].lchild==c)  
79.         cd[start]='0';        //结点c是f的左孩子,则生成代码0
80.       else
81.         cd[start]='1';                    //结点c是f的右孩子,则生成代码1
82.       c=f; 
83.       f=HT[f].parent;                   //继续向上回溯
84.     }                                     //求出第i个字符的编码      
85.     HC[i]=new char[n-start];          // 为第i 个字符编码分配空间
86.     strcpy(HC[i], &cd[start]);              //将求得的编码从临时空间cd复制到HC的当前行中
87.   }
88.   delete cd;                                  //释放临时空间
89. }                         // CreatHuffanCode
90. void show(HuffmanTree HT,HuffmanCode HC)
91. {
92.   for(int i=1;i<=sizeof(HC)+1;i++)
93.     cout<<HT[i].weight<<"编码为"<<HC[i]<<endl;
94. }
95. int main()
96. {
97.   HuffmanTree HT;
98.   HuffmanCode HC;
99.   int n;
100.  cout<<"请输入叶子结点的个数:\n";
101.  cin>>n;                 //输入赫夫曼树的叶子结点个数
102.  CreatHuffmanTree(HT,n);
103.  CreatHuffmanCode(HT,HC,n);
104.  show(HT,HC);
105.  return 0; 
106. }
目录
相关文章
|
1月前
|
存储 算法 编译器
数据结构实验之矩阵的运算器(二维数组)
本实验旨在通过团队合作,掌握数组和矩阵相关运算的代码实现,包括矩阵的加减、数乘、转置、乘法、n次方及行列式的计算。实验过程中,成员们需分工协作,解决编程难题,最终实现一个功能完备的矩阵计算器。通过本实验,不仅锻炼了编程能力,还加深了对数学概念的理解,同时培养了团队合作精神。
64 4
|
1月前
数据结构实验之串模式匹配问题
本实验旨在掌握串模式匹配技术,通过创建文本文件、实现单词计数与定位功能,最终构建一个包含文件建立、单词统计与定位、程序退出等选项的主菜单,以增强对字符串处理的理解与应用能力。
57 4
|
1月前
|
算法
数据结构实验之最长公共子序列
本实验旨在通过编程实践帮助学生理解串的基本概念及求解最长公共子序列的算法。实验内容包括使用动态规划方法设计并实现算法,以找出给定两序列的最大公共子序列。示例代码展示了如何通过构建状态矩阵和回溯路径来找到解决方案。实验总结指出,`memset()`函数用于内存初始化,且对于特定输入,程序能正确输出最长公共子序列之一。
57 4
|
1月前
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
45 4
|
1月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
60 4
|
1月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
86 4
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
58 4
|
2月前
|
算法
计科一二班算法数据结构实验9答案
计科一二班算法数据结构实验9答案
21 0
|
3月前
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。