DS博客作业05-树

1.本周学习总结

1.思维导图

2.谈谈你对树结构的认识及学习体会

树的学习,最大的难点就是递归函数的应用,很多地方使用到递归就会简便很多。但是在学习中的时候,我很难理解递归函数的内涵。很多的递归的函数传入的参数不能够理解它的意思。只能死记硬背,只有一些简单的递归我才看得懂。这也是我学这一章最大的困难。虽然基本上这一章的内容无非就是树的构造和一些查找,表达式的运算等,代码的思路上还是挺清晰,但是一涉及到递归的时候就不知道怎么下手。我能做的也只能先把代码框架理解清楚,涉及递归的内容,只能背下来。我问了很多同学他们学习的时候难处,很多跟我类似,遇见递归就怕了。我这周也尽力在看一些关与递归的讲解视频,凭上课那点课堂时间,实际上要理解是非常难的,我发现我看了一些视频后,对递归的了解有一定的增加,慕课上的视频很好。可以和课堂搭配使用,就是一定要花时间去。平时我的时间也比较紧张,很难系统的花一段长时间去学习,剩下几周我打算集中一段时间,好好根据视频琢磨一下递归。也当作是期末复习,这一章我相信把这个难点弄清楚,大致上就可以了的。

2.PTA实验作业

2.1.题目1:

2.1.1设计思路(伪代码)

main:
定义变量str和wpl记录权值
输入str
定义树的指针bt
利用函数BTree CreateBTree( string str , int i )构造树
调用Wpl函数计算权值,输出wpl;

建树函数:
动态分配bt空间new Tnode;
判断树是否空,如果str[1]==‘#‘代表根结点为空结点和根结点位置不满足题意返回NULL
头结点赋值:
利用孩子节点和双亲节点的位置关系递归构造树
(若双亲节点下标为i,左孩子下标为2i,右孩子下标2i+1)

返回根结点指针

Wpl函数:(传入地址型变量wpl,初始h为0)
如果结点为空,结束调用
如果寻找到叶子结点,开始计算:
wpl+=(bt->data-'0')*h;
递归左孩子树,右孩子树: 
Wpl(bt->lchild,h+1,wpl);//左子树权值
Wpl(bt->rchild,h+1,wpl);//右子树权值
wpl的值调用一次更改一次,随时保持最新状态。

2.1.2代码截图

2.1.3本题PTA提交列表说明

  • Q1:一开始计算权值设计的是int型函数,设计了返回值:

结果发现,height的值不能够保留,起不到累加的作用,代码一开始的给height的初值=0设计错误。

  • A1:后来考虑到wpl需要累加直接改成了无返回值的函数:
    &wpl直接可以做到递归中保留前值的作用,不需要放回值。

2.2.题目2:

2.2.1设计思路(伪代码)

建表达式二叉树InitExpTree:
定义树栈 node 存储数字
定义字符型栈 opchar存储运算符
定义p,a,b结点存储数据

while str【i】
 if  str 为数字 then 分配p结点空间将数字存到node栈中
else
switch(Precede(opchar栈顶运算符,str))//调用函数比较符号栈顶和现在的符号的优先级
{ 
case '<' 栈顶运算符优先级低:opchar.push(str) --从str中读取下一个字符入符号栈
case '=' 两个括号满足这个情况:直接出栈顶
case '>' 栈s运算符执行:数据node栈出2个数据存入a,b中,建立一棵小二叉树。opchar.pop( )把建完的符号出栈;再把整棵小二叉树p存入树栈node中。
}
end while

while 2个栈非空
数据栈出2个数据给a,b,继续建立一棵小二叉树。并且opchar.pop( )把建完的符号出栈;再把整棵小二叉树p存入树栈node中。
end while

最后把整棵树p赋值给T;


计算表达式树EvaluateExTree:
定义浮点型数 a b 存储运算数;
首先查找到叶子节点(数据节点)把所有字符转换成数字;
a,b分别存储树节点的左右孩子数据值;

switch(双亲结点(符号结点))
{
运算符号 '+' 返回 a+b;
运算符号 ‘-' 返回 a-b;
运算符号 '*' 返回 a*b;
运算符号 '/' 
if b为0 then输出有误
 else 返回a/b;
}

2.2.2代码截图



2.2.3本题PTA提交列表说明

  • Q1:一开始以为简单的建立一个栈就行:

  • A2:更改成

  • Q2:忘记把建好的小二叉树整棵输入到数据栈中,缺少了这一步

  • A2:加上这一步后树才算建好。

  • Q3:误以为结点数据就是数字型,直接去运算,其实本质上是字符型

  • A3:加上这一步:把结点字符转化为数值型数据

  • Q4:建树的时候没有考虑到栈中还有元素这一部分,导致建成的树不完整

  • A4:参考同学代码,增加了这一步代码。

2.3.题目3:

2.3.1设计思路(伪代码)

main:
定义mid/post数组
循环变量I,结点数量num
输入num
for I=0 to num 输入先后序列
end  for
定义bt并且调用函数建树
输出建好的树Print

CreateBt建树函数:
定义树节点bt并且分配内存
如果传入的结点数小于等于0,不合法返回NULL

for I=0 to num //寻找根节点在中间序列的位置
 if mid[i]==post[num-1] then 跳出 //寻找到了后跳出记录此时的I值
end  for

调用递归和I的值 根据关系,建立左右子树
lchild = CreateBt(mid,post,i);//利用递归分别建立左右孩子树 
rchild = CreateBt(mid+i+1,post+i,num-i-1);
bt->data=post[num-1];//根节点赋值 

树建好后返回bt

2.3.2代码截图


2.3.3本题PTA提交列表说明

  • Q1:首先把先序序列和后序序列搞反了。输入的时候以为先读入中序列,后读入后序列

  • A1:看清题目,后序在前,中序在后,交换了一下。

  • Q2:递归建左右子树的时候I的值处理出现错误

    中序后序和I的关系搞混了

  • A2:问了室友,重新理解了一遍形参。更改了才成功

3.阅读代码

3.1 题目

给定一棵二叉树,交换这个二叉树的左右孩子。

3.2 解题思路

巧妙的运用一个桥梁,来交换左右孩子,定义一个BITree t结点,起到中间变量的作用。其思路与c语言数组中的temp功能类似。

3.3 代码截图

3.4 学习体会

一开始看到这个题目,其实我也是有思路的,比如把数据结点取出来,用栈或者什么数组,把顺序交换一下在用来建树。这样也能够达到目的,但是我看了这个研究生题目的解题思路确实很吃惊。因为一眼看去,真的太容易了,但是也太难想到了,这就是我们上学期学到的数组中排序交换数字的功能。想不到在树中也能够用BiTree 定义一个类似与temp功能的结点,直接用这个结点去交换就行了,这样就不用在麻烦的根据我一开始的思路去用很多别的东西处理了,简单的一个t就能够完成,代码篇幅用了递归非常的简单。这个题目让我学会了很多东西追根溯源可以跟我们学过的东西结合到一起来,c语言的一些基础思想在任何时候都可以使用。以后谈到交换,就要首先思考能不能用类似的思路去解决问题。

posted @ 2019-05-18 19:38  秋斌  阅读(225)  评论(0编辑  收藏  举报