1.学习总结(2分)
1.1树结构思维导图
1.2 树结构学习体会
- 树的代码实现中大量使用到递归法,但是递归法我使用起来不是很灵活,因此做题的时候不顺畅。
- 树和二叉树的性质不熟悉,计算易错。
- 朋友圈、亲戚关系类型题目不能实现、并查集不会用。
2.PTA实验作业(4分)
2.1 题目1:jmu-ds-表达式树
输入一行中缀表达式,转换一颗二叉表达式树,并求解.
表达式只包含+,-,*,/,(,)运算符,操作数只有一位,且为整数(有兴趣同学可以考虑负数小数,两位数做法)。按照先括号,再乘除,后加减的规则构造二叉树。
2.2 设计思路(伪代码或流程图)
void InitExpTree(BTree &T,string str) { //建二叉表达式树
初始化运算符栈op,数字字符栈num;
将'#'进栈;
while(字符串不空){
if(str[i]不为运算符)
建立新节点T赋值为str[i]并进栈num ,将左右孩子置为空
else
switch(Precede(op栈顶运算符,str[i])){
case '<': 将str[i]进栈,从str读取下一个字符; break;
case '=': 退栈,从str读取下一个字符; break;
case '>': op栈顶运算符赋值给新节点T并出栈,num栈顶元素分别赋值给左右孩子,将T进栈num; break;
}
end
while(op栈顶运算符不为 # )
op栈顶运算符赋值给新节点T并出栈,num栈顶元素分别赋值给左右孩子,将T进栈num
end
double EvaluateExTree(BTree T){//计算表达式树
定义浮点型变量a,b;
利用递归把所有字符转换成数字;
switch(T节点不空){
case '+': 返回 a+b; break;
case '-': 返回 a-b; break;
case '*': 返回 a*b; break;
case '/': if (b为0) 输出"divide 0 error!";退出;
返回 a/b; break;
}
}
2.3 代码截图
2.4 PTA提交列表说明。
-
编译错误:多放了题目已给的函数进去
解决方法:删除多余函数 -
答案错误:输出的结果不对
解决方法①:检查发现把字符转数字一步出错,修改后输出的答案正确,但PTA还是不能通过
修改后:
解决方法②:经同学帮助找出错误,num的栈顶元素赋值给左右孩子使错误,应该先赋值给右孩子,再赋值给左孩子,否则会使a,b值反掉,使计算错误
解决方法③:如遇到除0,提示divide 0 error!
这一点没进行判断,除0时答案错误
2.1 题目2:jmu-ds-二叉树叶子结点带权路径长度和
二叉树叶子结点的带权路径长度指:叶子结点的权重路径长度。本题要求算出二叉树所有叶子结点的带权路径长度和。
2.2 设计思路(伪代码或流程图)
BinTree CreateBtree(string str,int i){ //创建树
定义len存放字符串长度
当节点不存在时,返回NULL;
建立新节点b,将str[i]的值赋予bt;
求出该节点所在高度
递归创建左子树;
递归创建右子树;
返回根节点
}
void wpl(BinTree b){//求wpl
if 树为空 退出;
if 树不为空
if b的左孩子节点不为空或 b的右孩子节点不为空
递归遍历找出叶子节点,累加其wpl值;
}
2.3 代码截图
2.4 PTA提交列表说明。
-
答案错误:求wpl的值处错误
解决方法:修改sum累加的式子
-
一个在写代码时遇到的问题
-
问题:求某节点所处高度,不会求
解决方法:求助同学了解为:b->H=log(i)/log(2)+1;
2.1 题目3:修理牧场
农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是Li的总和。但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木头花费15,总花费为35(大于32)。请编写程序帮助农夫计算将木头锯成N块的最少花费。
2.2 设计思路(伪代码或流程图)
PtrH create(ElemType arr[],int n){//创建哈夫曼树
定义ptrArr[n],
定义ptr,p;
初始化p;
将数组arr[]中的数存入ptr树,并初始化根ptr左右子树为空;
for i=1 to n
定义k1=-1,k2 表示数组中最小和次小的数
for j=0 to n
if (ptrArr[j]不空且k1为-1) k1=j; continue;
if (ptrArr[j]不空) k2=j; break;
end
for j=k2 to n
if (ptrArr[j]不空)
将数组中最小值赋值给下标为k1的,次小值赋值给下标为k2的
end
建立一棵新树p指向树根结点,根的值是两子树相加
最小权值作为p的左子树;
次小权值作为p的右子树;;
将指向新树的指针赋给ptrArr指针数组中k1位置;
k2位置则空;
end
return p;
}
2.3 代码截图
2.4 PTA提交列表说明。
-
问题:本题其实就是用题目给的数据创建一棵哈夫曼树,求其wpl值,我的主要问题在创建哈夫曼树的问题上。
解决方法:创建哈夫曼树的方法自己写不出来,最终通过百度找了方法 -
问题:对于课本上哈夫曼树的构造中
min1=min2=32767;
一直不知道是什么意思,最后查资料知道
3.截图本周题目集的PTA最后排名(3分)
3.1 PTA排名
3.2 我的得分:205(2分)
4. 阅读代码(必做,1分)
- 代码功能:构造哈夫曼树,求wpl
- 代码理解:该代码使用了优先队列,按元素从小到大,方便找出最小权值,将最小和次小权值的和入队继续比较,同样采用哈夫曼思想,相比之下我的修理牧场一题太过复杂。
- 优先队列:[https://blog.csdn.net/wyk1823376647/article/details/52048896]
- 代码地址:[https://blog.csdn.net/gdg_dys/article/details/60477022]