设计与开发第二次实验报告C#学习心得

本文探讨了编程新手常遇到的挑战,包括枚举类型的遍历、代码细节处理、注释编写及关注代码实现过程等方面的问题,并提供了相应的解决思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

※动手能力的匮乏是我目前在书写代码时的问题


1.枚举类型的遍历:

因为在程序中需要列举出一系列的常量供用户选择,而这些常量都存储在一个枚举类型中。明确问题之后,在网上搜索了一番,找到了如下的链接并帮助自己解决了这个问题:http://www.jb51.net/article/37385.htm;

尽管解决了一个问题,但在实现其他更深的拓展功能上,发现自己对枚举类型和switch...case循环理解不够深入,并且在遍历循环上理解也很肤浅,这个作为提高点写在这篇博文里方便自我提升。


2.代码书写过程中的细节问题:

细节很能体现一个人一件事,在书写代码过程中,也发现了细节这个问题。想起之前在实现类似于QQ登录的功能时,对字符串的处理上的一个细节问题:你在数据库中存储了一个var(10)的字符串,但实际过程中你却只存储了5个字符组成的字符串,在核对用户输入密码与数据库的密码是否一致时,需要考虑这个问题:假设密码为12345,用户输入的密码也为12345,数据库存储的也为12345(var(10)类型),但在实际比较过程仍然会出现登录不成功的问题,这是因为:你需要对字符串进行去空(.Trim())处理,数据库内部自动给未满10的字符串加上了一些空格从而达到数据的要求(暂且用0来代替这些空格),那么12345=1234500000就不成立。这体现了计算机严谨的思维,而这些严谨在实际上就体现在细节这个方面上;

加强对细节的关注与总结。


3.多写注释,并将注释写得干净简洁有逻辑:记得之前有在某篇文章上看到,一个程序的注释要大于其代码量的50%。


4.关注代码实现过程而不是代码的实现结果,多记录,多总结。

<think>我们正在处理用户关于哈夫曼树构建的实验报告及题目的请求。根据引用内容,哈夫曼树用于构造最优编码,提高信道利用率。构建过程包括:将n个字符作为叶子节点,然后不断合并两个权值最小的子树,形成新的子树,直到形成完整的哈夫曼树。我们将提供:1.实验目的2.实验原理(哈夫曼树构建算法)3.实验步骤4.示例题目及构建过程5.实验报告要求(可选)6.代码示例(可选,根据用户需求)注意:用户明确要求实验报告题目和示例,因此我们将重点放在实验题目和构建过程上。实验目的:掌握哈夫曼树的构建方法,理解哈夫曼编码的原理。实验原理:哈夫曼树(最优二叉树)是一种带权路径长度最短的二叉树。构建步骤:1.将n个权值(字符出现的频率)看作n棵二叉树的根节点,组成森林F。2.从F中选取两个根节点权值最小的树作为左右子树,构造一棵新的二叉树,新二叉树的根节点权值为其左右子树根节点权值之和。3.在F中删除这两棵树,同时将新得到的二叉树加入F。4.重复步骤2和3,直到F中只剩一棵树为止,这棵树就是哈夫曼树。实验题目示例:题目:给定一组权值W={7,5,2,4},构建哈夫曼树,并计算带权路径长度。实验步骤:1.初始化:将每个权值作为一棵单独的树,形成森林。即:节点集合为[7,5,2,4]。2.第一次合并:选择最小的两个权值2和4,合并成一棵新树,根节点权值为2+4=6。森林变为[7,5,6]。3.第二次合并:选择最小的5和6,合并成新树,根节点权值为5+6=11。森林变为[7,11]。4.第三次合并:选择7和11,合并成新树,根节点权值为7+11=18。此时森林中只有一棵树,即为哈夫曼树。树的结构:18/\711/\56/\24注:也可以有不同的形态(比如左右子树顺序不同),但带权路径长度相同。计算带权路径长度(WPL):叶子节点的权值乘以该节点到根节点的路径长度(边数),然后求和。节点7:权值7,路径长度1->7*1=7节点5:权值5,路径长度2->5*2=10节点2:权值2,路径长度3->2*3=6节点4:权值4,路径长度3->4*3=12WPL=7+10+6+12=35实验报告要求(可包含的内容):1.实验目的2.实验内容(题目描述)3.算法设计(包括数据结构定义、算法步骤描述)4.实验结果(构建的哈夫曼树图示、WPL计算)5.实验总结(心得体会)代码示例(C语言):由于用户提到了引用[1]和[2]中的实验报告,这里提供简单的哈夫曼树构建的代码框架。```c#include<stdio.h>#include<stdlib.h>#defineMAX100//哈夫曼树节点结构typedefstruct{intweight;//权值intparent,lchild,rchild;//双亲、左右孩子下标}HTNode,*HuffmanTree;//选择两个最小权值的节点voidSelect(HuffmanTreeHT,intn,int*s1,int*s2){intmin1=1000,min2=1000;//初始化为较大值*s1=*s2=0;for(inti=1;i<=n;i++){if(HT[i].parent==0){//未加入树的节点if(HT[i].weight<min1){min2=min1;min1=HT[i].weight;*s2=*s1;*s1=i;}elseif(HT[i].weight<min2){min2=HT[i].weight;*s2=i;}}}}//构建哈夫曼树voidCreateHuffmanTree(HuffmanTree*HT,int*w,intn){if(n<=1)return;intm=2*n-1;//哈夫曼树节点总数*HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用//初始化前n个节点为叶子节点for(inti=1;i<=n;i++){(*HT)[i].weight=w[i-1];(*HT)[i].parent=0;(*HT)[i].lchild=0;(*HT)[i].rchild=0;}//初始化后面的节点for(inti=n+1;i<=m;i++){(*HT)[i].weight=0;(*HT)[i].parent=0;(*HT)[i].lchild=0;(*HT)[i].rchild=0;}//构建哈夫曼树ints1,s2;for(inti=n+1;i<=m;i++){Select(*HT,i-1,&s1,&s2);//在[1,i-1]中选择parent为0且权值最小的两个节点(*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;}}intmain(){HuffmanTreeHT;intw[4]={7,5,2,4};CreateHuffmanTree(&HT,w,4);//输出哈夫曼树节点信息for(inti=1;i<=7;i++){printf("节点%d:权值=%d,双亲=%d,左孩子=%d,右孩子=%d\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);}free(HT);return0;}```运行结果示例(部分):节点1:权值=7,双亲=5,左孩子=0,右孩子=0节点2:权值=5,双亲=6,左孩子=0,右孩子=0节点3:权值=2,双亲=4,左孩子=0,右孩子=0节点4:权值=4,双亲=4,左孩子=0,右孩子=0//注意:这里节点3和4合并成节点4?实际上我们的代码中节点3和4在合并后成为新节点(节点5)的左右孩子,但新节点5的权值为6。然后节点2和节点5合并成节点6(权值11),最后节点1和节点6合并成节点7(权值18)。所以节点编号顺序为1,2,3,4,5,6,7。注意:代码中数组下标从1开始,0号位置不使用。实验报告题目建议:1.给定权值集合{3,7,8,2,5,8,4},构建哈夫曼树,并计算WPL。2.假设有5个字符,其出现频率分别为0.1,0.15,0.2,0.25,0.3,设计哈夫曼编码。3.比较哈夫曼编码等长编码的压缩效率。根据引用[2]:实验总结部分可以写通过实验对哈夫曼算法的理解,以及如何选择最小树等。最后,我们生成相关问题。</think>### 哈夫曼树构建实验报告及题目示例 #### 一、实验目的 1. 理解哈夫曼树的基本概念和构建原理 2. 掌握哈夫曼树的构造算法实现 3. 理解哈夫曼编码在数据压缩中的应用 4. 计算哈夫曼树的带权路径长度(WPL) #### 二、实验原理 哈夫曼树(最优二叉树)是带权路径长度最短的二叉树,构建核心步骤如下: 1. **初始化**:将$n$个权值作为$n$棵二叉树的根节点,组成森林$F$ 2. **合并最小树**:在$F$中选择两棵**根结点权值最小**的树作为左右子树,构造新二叉树 3. **更新权值**:新二叉树的根结点权值 = 左子树权值 + 右子树权值 4. **迭代构建**:将新树加入$F$,重复步骤2-3直到森林只剩一棵树[^1][^2] 带权路径长度计算公式: $$WPL = \sum_{i=1}^{n} w_i \times l_i$$ 其中$w_i$为叶结点权值,$l_i$为根到该结点的路径长度 --- #### 三、实验题目示例 **题目1:基础构建** 给定权值集合 $W = \{5, 3, 8, 2, 7\}$: 1. 画出哈夫曼树的构建过程 2. 计算WPL 3. 给出各叶节点的哈夫曼编码 **构建过程**: | 步骤 | 操作 | 森林状态 | |------|------|----------| | 1 | 初始 | $\{2\}, \{3\}, \{5\}, \{7\}, \{8\}$ | | 2 | 合并2+3=5 | $\{5\}, \{5\}, \{7\}, \{8\}$ | | 3 | 合并5+5=10 | $\{7\}, \{8\}, \{10\}$ | | 4 | 合并7+8=15 | $\{10\}, \{15\}$ | | 5 | 合并10+15=25 | $\{25\}$ | **WPL计算**: $$WPL = 2×3 + 3×3 + 5×2 + 7×2 + 8×2 = 6+9+10+14+16=55$$ **哈夫曼编码**: ``` 权值2: 000 权值3: 001 权值5: 01 权值7: 10 权值8: 11 ``` --- **题目2:应用设计** 某通信系统使用字符集 $\{A,B,C,D,E\}$,出现频率为: $A:0.35, B:0.2, C:0.15, D:0.15, E:0.15$ 1. 构建哈夫曼树 2. 为每个字符设计二进制编码 3. 计算平均编码长度 **解答关键**: 1. 将频率×100得权值:$\{35,20,15,15,15\}$ 2. 合并最小权值结点(注意同权值时的顺序选择) 3. 左分支标0,右分支标1 4. 平均长度 = $\sum (频率_i × 编码长度_i)$ --- #### 四、实验报告要求 1. **问题描述**:清晰说明实验任务 2. **算法设计**: ```c // 哈夫曼树存储结构 typedef struct { int weight; int parent, lchild, rchild; } HTNode; // 关键算法伪代码 void buildHuffmanTree(HTNode tree[], int w[]) { for(i=0; i<n; i++) // 初始化叶结点 tree[i] = {w[i], -1, -1, -1}; for(i=n; i<2*n-1; i++) { selectTwoMin(tree, &min1, &min2); // 选择两个最小权值 tree[i] = {tree[min1].weight + tree[min2].weight, -1, min1, min2}; tree[min1].parent = tree[min2].parent = i; } } ``` 3. **实验结果**: - 树形结构图示 - WPL计算过程 - 编码表(如:`A->10, B->111, ...`) 4. **复杂度分析**: - 时间复杂度:$O(n \log n)$(采用优先队列时) - 空间复杂度:$O(n)$ 5. **实验总结**: - 验证哈夫曼树WPL最短的特性 - 分析编码长度概率分布的关系 - 实际应用场景思考(如文件压缩算法)[^1] --- #### 五、扩展题目 1. **动态构建**:设计支持动态增加字符的哈夫曼树更新算法 2. **译码实现**:输入二进制串,根据哈夫曼树解码原文 3. **压缩率计算**:对比哈夫曼编码等长编码的压缩效率 $$压缩率 = \frac{\text{等长编码总位数} - \text{哈夫曼编码总位数}}{\text{等长编码总位数}} \times 100\%$$ > 实验提示:可通过数组(静态存储)或指针(动态存储)实现树结构,重点注意`selectTwoMin`函数的优化实现[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值