04-树

1.学习总结

1.1树结构思维导图


1.2 树结构学习体会

树相较于之前学习的,最大的区别就是,它可以有多个后继,很大一个特点就是操作时频繁出现递归,如果懂这段代码会觉得利用递归代码精简很多,但是不能看出代码功能的话,就比较难理解中间是怎么操作的。树的知识点也很多,光是遍历,就有先序后序中序层次遍历好几种,相应的有些方面功能也很强大,可以解决很多实际问题,比如哈夫曼树—修理牧场,交并集—朋友圈

2.PTA实验作业

2.1 题目1:7-8 jmu-ds-二叉树叶子结点带权路径长度和

2.2 设计思路

    定义字符串数组str,树bt,变量i,叶子结点带权路径长度和n,设n初值为0
    输入str
    求str长度len
    利用递归构造树bt
        若当前位置的字符str[i]为#,该结点为NULL
        否则 将该字符赋给bt结点
                 该结点高度为log(i)/log(2)+1
        根据二叉树顺序储存结点关系
                 2i位置元素构成bt结点的左孩子
                 2i+1位置元素构成bt结点的右孩子
    若树不为空
          访问叶子结点,n累加该结点的值与其高度的乘积
          访问左子树的叶子结点,n累加该节点的值与其高度的乘积
          访问左子树的叶子结点,n累加该节点的值与其高度的乘积
     输出n  

2.3 代码截图

2.4 PTA提交列表说明。

求叶子结点带权路径长度和需要实现俩部分内容:

              (1)找到叶子结点,利用递归,找到左右节点皆空的结点
              (2)知道这些叶子结点的高度

1.遇到的主要问题是第二个,如何求某个结点的高度,只学习过求树的高度。我们知道高度为H的树,节点数i最大为2^H-1,解出来H=log(i)/log(2)+1。将高度也加入树的结构体中,方便后面计算操作。

2.调用树的构造函数传参时,i传入的是1,一定要给它赋值,否则输出为0,调试会发现不会执行那些递归构造语句,自然长度和为0了,赋值为1,是因为第一个字符,也就是str数组中str[0]位置元素#不是结点

2.1 题目2:7-7 朋友圈

2.2 设计思路

    定义总人数sn,俱乐部数cn,数组t[n]代表所有人的序号,ans,用-ans表示朋友圈人数
    输入sn,cn
    将数组t所有值初始化为-1,代表各自所属的集合
    当cn--不为0时,执行下列循环语句
        输入该俱乐部的人数sum
        输入根x
           当sum--不为0时,执行循环语句
                输入成员y
                将x,y合并
                查找x,y集合编号fx,fy
                 如果二者相等,已经在一个集合了,return
                 如果不等
                     x,y划入一个集合
                    t[fx]变为t[fx]和t[fy]之和
                    fy的集合编号变为fx
            找出最小的t[fx],赋给ans
     cn为0时循环结束    
    输出-ans            
思路通俗版:
    所有人的t初值为-1,a,b在一个朋友圈,设a为根,a,b在一个朋友圈,将a,b合并,t[a]=-1,t[b]=-1,将它们合并的值
赋给t[a],t[a]变为-2,t[b]变为a的序号,t[a]=-2代表朋友圈内有俩个人,继续将t[]值为负值的与根相合并,因为学生编号从1开始,t[]值为正的都已经找到相应集合了。所以可以通过找最小的t[]值,它的绝对值代表最大的朋友圈数。

2.3 代码截图

2.4 PTA提交列表说明。

知识点:朋友圈主要是利用交并集,将朋友关系的元素合并到一个集合

错误:忽略了如果每个俱乐部都不超过一个成员的情况,因为同俱乐部才有可能存在朋友关系

改正:判断每个俱乐部的人数,如果都不超过一个,最大的朋友圈即为1

2.1 题目3:6-4 jmu-ds-表达式树

2.2 设计思路

构建表达式树:
   定义栈 q存储数字
   定义栈 op存储运算符
    将#入栈op
   遍历字符串str
    如果str[i] 为数字
      创建节点T
      将str[i]的值赋给T并置左右孩子为空
      将T入栈q
    如果str[i]为运算符 
      调用Precede函数,判断op栈顶元素与str[i]的优先级大小
      如果栈顶元素优先级小
         将运算符入栈op;
      如果优先级一样大
         将op栈顶元素出栈
      如果栈顶元素优先级大
         创建新的节点T
         出栈op栈顶元素
         并将栈顶元素的值赋给T
          取q栈顶元素赋给T的右孩子再出栈栈顶元素
          取q栈顶元素赋给T的左孩子再出栈栈顶元素
          如果栈op中仍有运算符
                 创建新的节点T
         出栈op栈顶元素
         并将栈顶元素的值赋给T
          取q栈顶元素赋给T的右孩子再出栈栈顶元素
          取q栈顶元素赋给T的左孩子再出栈栈顶元素
计算表达式树:
        定义变量a b 存储运算数;
        递归遍历树
        把所有字符转换成数字;
        a,b分别存储T节点的左右子树;
       判断T值即运算符
       如果为+号,计算a+b的值,并返回
       如果为-号,计算a-b的值,并返回
       如果为*号,计算a*b的值,并返回
       如果为/号
            如果b为0,输出divide 0 error!
            如果不为0,计算a/b的值,并返回

2.3 代码截图





2.4 PTA提交列表说明。

错误:非零返回

修改:输出结果多出一个0,将return 0改为exit(0)后正确

return 0和exit(0)的区别:return 0是返回函数调用,如果返回的是main函数,则为退出程序;exit(0)是在调用时强行退出程序

3.截图本周题目集的PTA最后排名

3.1 PTA排名

3.2 我的得分:2.5分

4. 阅读代码

优先队列:[https://blog.csdn.net/wyk1823376647/article/details/52048896]
代码地址:[https://blog.csdn.net/gdg_dys/article/details/60477022]

代码功能:7-7修理牧场

代码优点:

用优先队列这一条语句就可以实现队列元素按从大到小,小的优先出队,代码精简了很多,思路也很巧妙,将木头锯成俩段,再将长的那段锯成俩段,重复操作,累加每一次被锯木头的长度,如何让累加值最小,也就需要保证每次锯的木头是由较小的俩根组成,这也就是哈夫曼树的构造原理,转而构造哈夫曼树

5. 代码Git提交记录截图



posted @ 2018-05-05 19:56  我是纪予哇  阅读(181)  评论(1编辑  收藏  举报