博客作业04--树

1.学习总结

1.1树结构思维导图

1.2 树结构学习体会

  • 由于树的这部分代码使用了大量的递归,导致许多思路变得很抽象,有些难以理解,对很多细节和内容掌握的并不深刻,很多代码也都是看着课本写的。树虽然有些难度,但是树结构可以提高算法的效率,节约时间,这部分的作用还是很大的。

2.PTA实验作业

题目1:6-3 先序输出叶结点

1.设计思路

遍历树
若BT->Left==NULL&&BT->Right==NULL,则为叶子节点输出
然后再递归判断BT的左孩子节点和右孩子节点是否为叶子节点

2.代码截图

3.PTA提交列表说明

  • 无问题。

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

1.设计思路

计算二叉树
若T->data为数字字符,则返回对应的数值
若T->data为运算符ch,则利用递归返回EvaluateExTree( T->lchild ) ch  EvaluateExTree( T->rchild )的值。
特别注意的是ch==/时,需要对分母EvaluateExTree( T->rchild )进行判断,若为0时,则提示错误。

构建表达式树
建立两个栈,一个存放运算符,一个存放树节点
遍历for i=0 to str[i]==0
    若str[i]为数字字符,则创建一个data为str[i],左右孩子都NULL的节点t,并将t推进树栈。
    若str[i]为运算字符
        则将str[i]对应的运算符与运算符栈栈顶的运算符,比较优先级。
        若栈顶的运算符优先级高,则两次取出树栈的栈顶,创建节点CreateExpTree( t , e2 , e1 , Op.top() ),再将t存入树栈,再把运算符的栈顶出栈,直到运算符栈顶与str[i]优先级相等。
end for
while(op.size())
     把运算符栈中的剩余运算符一个一个出栈,并且分别创建节点。
end
将T指向创建的表达式树。

2.代码截图


3.PTA提交列表说明

  • 本题借鉴了他人代码,并且理解了思路。
    在计算二叉树中,分母为0时,我用return 0,导致答案错误.
    解决方法:改为exit(0)。

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

1.设计思路

利用递归创建二叉树
    因为第i个节点的左孩子为2i,右孩子为2i+1
    所以利用这个关系将顺序二叉树转为链式二叉树,bt->lchild =CreateBTree(str,2*i), bt->rchild             =CreateBTree(str,2*i+1)。
    递归出口为   if(i>len-1 || i<=0) return NULL,if(str[i]=='#') return NULL。

递归求WPL
    先设置一个全局变量wpl
    若BT==NULL,则返回空
    若BT为叶子节点,则累加wpl += (BT->data-'0') * floor
    BT指向孩子节点时,floor就加1 
    所以递归Wpl(BT->lchild,floor+1),Wpl(BT->rchild,floor+1);

2.代码截图


3.PTA提交列表说明

  • 一开始忘将节点的数值字符转化为对应的数值,导致计算错误。
    解决方法:BT->data-'0'

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

3.1 PTA排名

3.2 我的得分:2.5

4. 阅读代码

寻找两个节点的最低公共祖先

TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {

        if(!p || !q) return NULL;

        vector<TreeNode*> path1,path2;
        findPath(root,p,path1);
        findPath(root,q,path2);

        if(path1.empty() || path2.empty()) return NULL;

        int i = 0;
        while(i<path1.size() && i<path2.size() && path1[i]==path2[i]) i++;

        return path1[i-1];
}

bool findPath(TreeNode *root, TreeNode *p, vector<TreeNode*> &path){

        if(!root) return false;
        if(root==p) {
            path.push_back(p); 
            return true;
        }
        path.push_back(root);
        bool flag1 = findPath(root->left,p,path);
        if(flag1) return true;
        bool flag2 = findPath(root->right,p,path);
        if(flag2) return true;

        path.pop_back();
        return false;
}
  • 如果是二叉搜索树,就简单了,如果当前节点均小于(大于)这两个节点,那么他们的最低公共祖先一定在当前节点的右子树(左子树)中,然后递归找,直到遇到某个节点,使得这两个节点不在同一侧,那么那个节点就是他们的最低公共祖先。但如果不是二叉搜索树,我们可以遍历树,找到这两个节点,并记录从根节点到它们的路径,然后在这两条路径上找它们的第一个非公共节点。

5. 代码Git提交记录截图

posted @ 2018-05-05 19:45  oracler  阅读(380)  评论(0编辑  收藏  举报