• DS博客作业05--树


    1.本周学习总结

    1.思维导图

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

        1.通过这周的学习,我学到了有关树的知识,其中个人认为最重要的就是建树,和树的遍历了。这些算法大多是通过递归的算法来实现的。而我个人认为递归是一个难懂的算法,因为它的递归是一层一层的,算完后还需要返回回去,讲真的很难搞懂,要花时间去理解。
        2.在学习中接触最多的就是二叉树了,我学到了许多有关二叉树的性质,像是它的结构啦,还有它的父亲结点,兄弟结点的性质等等。还学到了树还有森林,以及二叉树和他们两者之间的转换。
        3.在树的遍历中,分为很多种,有先序遍历和中序遍历和后续遍历以及层次遍历。也正因为有这么多的遍历,所以也衍生出许多的建树的方法,这些都是需要掌握的。
        4.这次的学习和之前的不一样,难度大多了,因为之前的pta的题目,那些都是代码量大但是比较好理解,但是这次的题目,代码量小,但是理解起来却很困难,就比如书上的代码,那些都是基础的,但是理解起来却要很久,要是没有书上的注释的话,可能要花更长的时间,这次的pta题目有挺多是不会写的,有许多是实在想不出来然后参考参考同学的代码或者网上的代码,但是却看不懂,要完成一题用了很长的时间。
        5.总的来说,这次之所以会觉得学得比较困难,是因为递归的算法不好搞懂,虽然代码量少,但却不易理解,个人认为是刷的题不够多,不过之前有个牵强的想法,就是等把算法搞懂了才去写代码,但是有好多人他们都是在还没搞懂的情况下就去写代码,并从中理解了算法,所以以后不能拖了,不能再给自己拖拉的机会,要学习其他同学在打代码中学到知识。
    

    2.PTA实验作业

    2.1.题目1:表达式树

    2.1.1设计思路(伪代码)

    void InitExpTree(BTree &T, string str)  //建表达式的二叉树
        将'#' 进栈;
        while str[i] then
            if str[i]是数字
               新建p结点
                p->data=str[i++];
                左右孩子置为空;
                p入栈node;
            end if
            else //为运算符 
                调用Precede函数比较op栈顶元素与str[i]大小
                如果函数值为'<'
                    str[i]进栈; 
                如果函数值为'='
                    出栈;
                如果函数值为'>'   
                    取node栈顶元素赋值给a;
                    出栈;
                    取node栈顶元素赋值给b;
                    出栈; 
                    CreateExpTree(p,b,a,opchar.top());
                    opchar出栈;
                    p入栈node;
                    i--;
            end else
            i++;        
        end while 
        while 栈node和opchar均不为空 then 
            取node栈顶元素赋值给a;   出栈;
            取node栈顶元素赋值给b;   出栈; 
            CreateExpTree(p,b,a,opchar.top());
            opchar出栈;
            p入栈node;
        end while
        T = p;
    
    double EvaluateExTree(BTree T)//计算表达树
        定义浮点型 a,b;
        if 树不为空
            if 左右孩子均不为空 
                返回 T->data-'0';
            a=EvaluateExTree(T->lchild);
            b=EvaluateExTree(T->rchild);
            判断 T->data
                如果是 '+'
                    返回a+b;
                如果是 '-'
                    返回 a-b;
                如果是 '*'
                    返回 a*b;
                如果是 '/':
                    if 除数为0 
                        输出"divide 0 error!";
                        退出;
                    end if;
                    返回 a/b;  
        end if 
    

    2.1.2代码截图



    2.1.3本题PTA提交列表说明

    • Q1:讲真的这题是真的难,一开始是完全没有思路的,所以就参考参考书上的代码,但是太长了不好理解。
    • A1:后来看到有同学已经写出来了,所以有不懂的部分就去问明白,勉勉强强的才打完了。
    • Q2:太粗心了,因为一点点的小错误,让我代码看了大半天,书也看了大半天,到最后实在找不出来哪错了,放到VS上调试。
    • A2:switch语句中忘了break,才会出现错误。讲真的VS确实好用。
    • A3:还有错误就是stack node中,一开始BTree写成了int。
    • A4:没次取栈的元素时几乎是要出栈。

    2.2.题目2:二叉树叶子结点带权路径长度和

    2.2.1设计思路(伪代码)

    typedef struct node
    {
        char data;
        struct node *lchild, *rchild;
    } tree, *Tree;
    
    int main()//主函数 
        定义字符串 s;
        定义 sum = 0;
        输入 s;
        Tree T;
        T=CreatTree(s, 1);
        CountWPL(sum, T,0);
        输出 sum;
        
    Tree CreatTree( string s, int i)//建树函数 
        Tree T;
        if i小于字符串长度 
            if s[i] 为 '#'
                T = NULL;
            end if 
            else
                生成新结点 
                T->data = s[i];
                T->lchild=CreatTree( s, 2 * i);
                T->rchild=CreatTree( s, 2 * i + 1);
        end if 
        else T = NULL;
        return T;
    
    void CountWPL(int &sum, Tree T,int i)//计算结点带权路径长度和 
        if T为空 sum += 0;
        else
            if 左右孩子均非空 
                sum += (T->data - '0')*i;
            CountWPL(sum, T->lchild,i+1);
            CountWPL(sum, T->rchild,i+1);
            end if 
    

    2.2.2代码截图


    2.2.3本题PTA提交列表说明

    • Q1:刚开始计算的函数定义为 void CountWPL(int sum, Tree T,int i),发现有错误。
    • A1:后来修改为 void CountWPL(int &sum, Tree T,int i)以做到sum递归中保留前值的作用。这是上课老师讲的,所以就采用了。不然其他方法很麻烦。
    • Q2:有一个小细节没注意到出现错误,放到VS中就发现了。
    • A2:就是T->data是字符型的,是要需要减去‘0’进行转换。

    2.3.题目3:根据后序和中序遍历输出先序遍历

    2.3.1设计思路(伪代码)

    typedef struct node{
    	int data;
    	Btree lchild;
    	Btree rchild;
    }BTNode;
    
    int main()//主函数
               定义mid/post数组
               循环变量I,结点数量num
               输入num
               for I=0 to num 输入先后序列
               end  for
               Btree bt=CreateBt(mid,post,num)
               输出Preorder:
    	   PrintPreOrder(bt)
    
    Btree CreateBt(int mid[],int post[],int num )//建树函数:
               定义树节点bt并且分配内存
               如果num<=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:这个问题真的很头疼,实在不懂,就是这个

      里面的创建右孩子的形参为什么要这样写我搞了很久。
    • A2:这种东西我是肯定理解不来,所以就去问其他的同学,最后才理解过来。

    3.阅读代码

    3.1 题目:求二叉树的宽度

    3.2 解题思路

    levelnumber函数利用数组a并用高度h作为下标实现了每个高度的结点求和也就是二叉树每一层的宽度,再利用fun函数中调用levelnumber函数取得数组a,接着在数组a中取最大值并返回,完成求二叉树宽度的功能。
    

    3.3 代码截图

    3.4 学习体会

    • 因为这道题在上次考试中出现,所以网上找了这段代码,这题我考试的时候没来得及就没写了,不过当时看这题的时候觉得这题应该挺简单的,但是实在没办法,在有原题目还没写的情况下我实在不想冒险去写还没接触的题目,个人认为上述代码容易理解,fun直接返回宽度。
  • 相关阅读:
    cocos代码研究(6)有限时间动作类(FiniteTimeAction)学习笔记
    cocos代码研究(5)Action学习笔记
    cocos代码研究(1)Node学习笔记
    cocos代码研究(2)Label学习笔记
    顽石系列:Linux基础笔试
    Spring笔记:事务管理
    Spring笔记:AOP基础
    Spring笔记:IOC基础
    MyBatis:学习笔记(4)——动态SQL
    Linux:进程管理
  • 原文地址:https://www.cnblogs.com/wcrbailun/p/10886860.html
Copyright © 2020-2023  润新知