博客作业04--树

1.学习总结

1.1树结构思维导图

1.2 树结构学习体会

  • 应用树可以解决一对多的问题,这在以前是难以解决的,比如家谱,朋友圈这类的问题,作为一种新的数据结构,我觉得是很实用的,但是很难。学习树结构的困难就在于对于递归算法的掌握程度不够高,而树很多都是用递归的,之前学递归的时候就不太会,现在要用到递归才体会到了书到用时方恨少的感觉,而且树的知识太多了,理解是能理解,但是很难记。
    利用树结构可以实现哈夫曼编码,可以实现并查集的功能来处理家谱或者朋友圈这类的问题,还有用在数据库中,时间复杂度比较低。

2.PTA实验作业

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

2.2 设计思路

建树:
建立一个存放符号的栈op,和存放根结点的栈root
往符号栈op中存入#
while(字符串未遍历完)
    如果是数字
        定义一个根节点并初始化并且值为这个数字
        将这个根节点入根节点栈root
    否则
        while(op栈的栈顶优先级大于此时遍历的符号)
            定义一个根节点并初始化并且值为op栈顶元素
            op栈顶元素出栈
            root栈出栈两个元素作为刚定义的根节点的左右孩子
            入栈这个根节点
        如果(op栈的栈顶优先级小于此时遍历的符号)
            将这个符号入栈到op栈
        否则
            op栈出栈
while(栈顶元素不为#即还有需要建立的结点)
    定义一个根节点并初始化并且值为op栈顶元素
     op栈顶元素出栈
     root栈出栈两个元素作为刚定义的根节点的左右孩子
    入栈这个根节点
根节点为此时root栈的栈顶
计算:(简要说明)
非递归后序遍历遇到数字入栈,遇到符号就出栈两个元素计算然后将结果入栈
最后的栈顶元素为结果

2.3 代码截图


2.4 PTA提交列表说明


1.遇到除数为0时,没有中止程序而是return 导致错误
2.计算时栈定义成int类型的,应该定义成double类型

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

2.2 设计思路

建树成功后求WPL:
定义一个静态局部变量WPL
如果BT不为NULL
        如果BT为叶子节点
            WPL=WPL+权重乘与高度减1
        递归(BT的左孩子,高度加1)
        递归(BT的右孩子,高度加1)
否则
    返回WPL

2.3 代码截图


2.4 PTA提交列表说明


题目中空孩子的孩子也要用#输入表示孩子为空,在建树的时候没考虑到导致错误

2.1 题目3:7-7 朋友圈

2.2 设计思路

定义一个pre数组表示根的数组并初始化
输入俱乐部的个数n和学生人数m
for i=1 to m
    输入此俱乐部的人数number
    定义一个 a数组长度为俱乐部人数加一
    for j=1 to number
        输入a[i]
    for j=2 to number
        将a[j-1]的根节点设为a[j]
for i=1 to n
    寻找根节点相同的人并统计人数
    如果人数大于max max=人数
输出max

2.3 代码截图

2.4 PTA提交列表说明


一开始对这种数组的并查集不会用,不明白根节点的意义,写着写着才会。

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

3.1 PTA排名

3.2 我的总分:285

4. 阅读代码

代码:

    stack <Bt> Family;
    int n , m , pre=0 ;
    Bt Anc = new Node , p = Anc ;
    cin >> n >> m >> Anc->name ;
    getchar();
    Anc->son = Anc->bro = Anc->par = NULL;
    Family.push( Anc );
    while( --n ){
        string name;
        getline( cin , name );
        int cnt = count( name.begin() , name[i].end() , ' ' );
        Bt add = new Node;
        add->name = name.substr( cnt );
        add->son = add->bro = NULL;
        cnt /= 2;
        if( cnt > pre ){
            p->son = add;
            add->par = p;
            Family.push( p );
        }
        else if( cnt == pre ){
            p->bro = add;
            add->par = p->par;
        }
        else{
            for( int i = 1 ; i<=pre-cnt ; i++ )
                Family.pop();
            p = Family.top()->son;
            while( p->bro )
                p = p->bro;
            p->bro = add;
            add->par = p->par;
        }
        p = add;
        pre = cnt;
    }

功能:pta家谱处理的建树。
一开始做这道题我也想着用树做的,但是由于不会用树,只会一丢丢的二叉树,所以最后用了伪并查集做,我觉得用树还是比较优秀的。

这里获得没有空格的子串还是比较巧妙的,运用了字符串的函数,数出空格个数再获得子串。
这是吴军霖同学的代码,详情请见 吴俊霖的pintia.cn

5. 代码Git提交记录截图

posted @ 2018-05-05 19:51  你们走啊  阅读(233)  评论(4编辑  收藏  举报