码迷,mamicode.com
首页 > 其他好文 > 详细

第04次作业-树

时间:2018-05-05 16:50:43      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:技术分享   序列   忘记   tps   技术   公式   search   com   时间   

1.学习总结

1.1树结构思维导图
技术分享图片
1.2树结构学习体会

1)树和二叉树是难点,但着实是重点,树的一些基本计算公式应牢记。
2)课本递归好理解,真正自己写的时候总是无从下手,PTA更需多加练习。
3)学完树,更加体会到写代码之前学写伪代码的重要性。

2.PTA实验作业

题目一:6-4 jmu-ds-表达式树(25 分)

输入一行中缀表达式,转换一颗二叉表达式树,并求解.
表达式只包含+,-,*,/,(,)运算符,操作数只有一位,且为整数(有兴趣同学可以考虑负数小数,两位数做法)。按照先括号,再乘除,后加减的规则构造二叉树。

2.设计思路:

/*建表达式二叉树*/
定义树栈 s1 存储数字
定义字符型栈 s2 存储运算符
‘#’入栈s2;
while 字符串不空
    if str[i] 为数字
      then 创建树节点,此节点赋予str[i]的值,并置其左右孩子为空后再次入栈s1;
    else 
      调用Precede函数
      if ‘<’
        then 运算符入栈s2;
      if‘=‘
        then s2栈顶元素出栈
      if‘>‘
        then 创建新的树节点并赋予s2栈顶元素值,右左孩子分别取s1栈顶元素后再次入s1栈;
          end
while 栈s2中仍有运算符
    创建新的树节点并赋予s2栈顶元素值,右左孩子分别取s1栈顶元素后再次入s1栈;
      end
/*计算表达式树*/
定义浮点型数 a b 存储运算数;
利用递归把所有字符转换成数字;
a,b分别存储树节点的左右子树;
while 树节点存在
    if ‘+‘
      then 返回 a+b;
    if‘-‘
      then 返回 a-b;
    if‘*‘
      then 返回a*b;
    if‘/‘
      then if b不为0
         返回a/b;
           end
  
      

3.代码截图
技术分享图片
技术分享图片
技术分享图片
技术分享图片
4.PTA提交列表说明
技术分享图片

  • 多种错误:粗心大意把a*b打成了a-b
    解决方法:修正a*b
  • 多种错误:没有考虑遍历完字符串后运算符栈中还存在运算符的可能
    解决方法:多一个while判断语句

    while(s2.top()!=‘#‘){
        T=new BTNode;
        T->data=s2.top();
        s2.pop();
        T->rchild=s1.top();
        s1.pop();
        if(!s1.empty()){
        T->lchild=s1.top();
        s1.pop();   
        }
        s1.push(T);
    }

    题目二:6-1 jmu-ds-二叉树操作集(20 分)

    本题要求用层次法创建二叉树,层次法输入序列是按树的从上到下从左到右的顺序形成,各层的空节点用字符 #表示

2.设计思路:

/*根据层次字符序列创建二叉树*/
定义树型指针 *T;
定义树形队列 Q;
if str[0] 非空
  then 创建 BT 新节点,并赋予值str[0];
      BT左右孩子都置空;
      BT入队;
while 队列非空
     队头元素出队并赋予T;
     if str[++i] 为#
       then T的左孩子节点为空;
     else
        T的左孩子节点赋予元素str[++i]的值;
    T的左孩子的左孩子右孩子分别置于空;
    T的左孩子入队;
if str[++i] 为#
       then T的右孩子节点为空;
     else
        T的右孩子节点赋予元素str[++i]的值;
    T的右孩子的左孩子右孩子分别置于空;
    T的右孩子入队;
      end

3.代码截图
技术分享图片
技术分享图片
技术分享图片

4.PTA提交列表说明
技术分享图片

  • 段错误:不知道如何建树,左右孩子节点遍历完后如何遍历下一节点
    解决方法:利用队列,左右孩子判断完便入队,下一次循环队列元素出队,即指向节点的左孩子,以此类推。
  • 格式错误:题目要求所有递归遍历输出都要带有空格
    解决方法:递归遍历的同时输出空格,eg:

    if(BT->lchild){
        cout<<" ";
        PreOrder(BT->lchild);
    }
    if(BT->rchild){
        cout<<" ";
        PreOrder(BT->rchild);
    }

    题目三:7-8 jmu-ds-二叉树叶子结点带权路径长度和(25 分)

    二叉树叶子结点的带权路径长度指:叶子结点的权重路径长度。本题要求算出二叉树所有叶子结点的带权路径长度和。

2.设计思路:

/*创建树*/
定义链表 str 存储输入的字符
定义树形指针 *bt
利用getchar()把输入的第一个字符吃掉
其余字符存储到 str 中;
while str[i++] 不为‘#‘
      then 建立新树节点bt;
       将str[i]的值赋予bt;
       依次递归遍历bt的左子树和右子树;
          end
/*求叶子节点带权路径长度和*/
定义整型字符 h 存储叶子节点所在的高度
定义整型字符 s 存储运算结果
if bt的左右孩子节点都为空
  then bt节点字符数转换为数字a;
      s+=a*高度;
if bt的左孩子节点不为空||bt的右孩子节点不为空
  then 采用递归遍历查找出叶子节点;

3.代码截图
技术分享图片
技术分享图片

4.PTA提交列表说明

技术分享图片

  • 部分正确:忘记树存储的是字符而不是数字
    解决方法:每一个data值都要转换为数字,即s+=h*(bt->data-‘0‘);
  • 部分正确:只考虑了特殊情况:叶子节点都在最后一层,导致编译一直只通过测试点0
    解决方法:在每一次找出来叶子节点时,都要实时更新其所处的高度

    3.PTA最后排名

    3.1PTA排名截图
    技术分享图片
    3.2我的总分
    2分

    PTA总分在180--230分:2分(必做题大部分做完)

    4.阅读代码

    题目:二分查找算法,斐波那契数列的递归及非递归。
    具体代码实现:

    #include<stdio.h>  
    int binarry_Search(int arr[], int len, int value){  //采用左闭右闭区间方式   
    int left=0,right=len-1;  
    int mid;  
    while(left<=right){  
        mid=left+((right-left)>>1);   //(left+right)/2;  
        if(value<arr[mid]){  
            right=mid-1;  
        }  
        else if(value>arr[mid]){  
            left=mid+1;  
        }  
        else{  
            return mid;  
        }  
    }  
    return -1;  
    }  
    int binarry_Search2(int arr[], int len, int value){     //采用左闭右开区间方式   
    int left=0,right=len;  
    int mid;  
    while(left<right){  
        mid=left+((right-left)>>1);   //(left+right)/2;  
        if(value<arr[mid]){  
            right=mid;  
        }  
        else if(value>arr[mid]){  
            left=mid+1;  
        }  
        else{  
            return mid;  
        }  
    }  
    return -1;  
    }  
    //使用非递归的时间复杂度为:O(logN),倒过来分析,比如一个数通过二分查找要找三次找到,那么这个有序数组的个数为2^3=8,则次数 time=logN;  
    //空间复杂度为:O(1),创建的临时变量为常数个;  
    int recur_bin_Search(int arr[],int left,int right,int value){   //使用递归实现二分查找   
    int mid;  
    if(left<right){  
        mid=left+((right-left)>>1);  
        if(value<arr[mid]){        
            right=mid;  
        return  recur_bin_Search(arr,left,right,value);  
        }  
        else if(value>arr[mid]){  
            left=mid+1;  
        return  recur_bin_Search(arr,left,right,value);  
        }  
        else{  
            return mid;  
        }  
    }  
    return -1;  
    }  
    //递归方式的时间复杂度:函数每次执行的时间复杂度为O(1),执行递归的次数同非递归的二分查找次数,故时间复杂度也是O(logN);  
    //空间复杂度:O(1);  
    int main(){  
    int arr[]={1,3,5,6,7,8};  
    int len=sizeof(arr)/sizeof(int);  
    int m=recur_bin_Search(arr,0,len,8);  
    printf("%d\n",m);  
    return 0;   
    }  
    优点:
  1. 对折半查找的理解更加深刻
    技术分享图片

2.此代码条理清晰让人易懂,笔者分别写了递归和非递归两种方法,通过比较更让我们体会颇深
代码相关地址:https://gitee.com/tanghuan5678/Data-Struct/commit/3989e178cf02431050ab746b39b2964e3477a1ac

5.代码Git提交记录截图

技术分享图片

第04次作业-树

标签:技术分享   序列   忘记   tps   技术   公式   search   com   时间   

原文地址:https://www.cnblogs.com/tanghuan/p/8992760.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!