DS博客做业05--树

1.思惟导图及学习体会

1思惟导图

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

  • 1. 树形结构属于非线性结构,经常使用的树形结构有树和二叉树。树是由n(n>=1)个有限节点组成一个具备层次关系的集合。树的基本术语有:结点的度与树的度;分支节点与叶子结点;路径与路径长度;孩子结点、双亲结点和兄弟结点;结点层次和树的高度等等。树有多种类型,可分为二叉树和哈夫曼树等,其中二叉树又可分为彻底二叉树和满二叉树。 在树中主要学习了二叉树和哈夫曼树这种树。
  • 2. 二叉树:二叉树是一种特殊的树。二叉树的特色是每一个结点最多有两个儿子。二叉树的存储结构能够有顺序存储结构和连式存储结构。能够经过二叉树的疏密以及题目要求等来决定树的存储结构。二叉树遍历的方法有先序遍历、中序遍历、后序遍历与层次遍历四种方法。不论在树的创建或其余基本运算中基本是要运用到递归,代码量少,可是理解起来不容易,并且错误地方不容易调试看出来。
  • 3. 树的学习仍是学的更懵逼了,特别是一开始递归部分很差理解,并且这章节须要记住的知识点不少,孩子节点、兄弟节点、满二叉树、彻底二叉树等等一堆东西,我以为我脑子已经不够用了,PTA上的题目以及不友好了,特别是表达式还有一堆的编程题,还有须要递归的地方,以及此次大做业,能写出来感受真是厉害了,这学期真是不容易啊,学的要死要活的...转专业来不及了都

2.PTA实验做业

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

输入一行中缀表达式,转换一颗二叉表达式树,并求解.
表达式只包含+,-,*,/,(,)运算符,操做数只有一位,且为整数(有兴趣同窗能够考虑负数小数,两位数作法)。按照先括号,再乘除,后加减的规则构造二叉树。
如图所示是"1+(2+3)*2-4/5"代数表达式对应二叉树,用对应的二叉树计算表达式的值。 转换二叉树以下:

2.1.1设计思路(伪代码)

void InitExpTree(BTree &T, string str) //建表达式的二叉树
创建字符栈op和树根栈node
建立树结点p等于NULL,a,b
定义i=0表示循环变量 定义字符来存判断两符号的优先关系的函数返回的符号
while 表达式str未结束
    if str[i] 是数字字符 then
       建立树节点p
        将结点存入树栈node中 node.push(p)
     else if str[i]是运算符 then
         if op.empty() then op.push(str[i])   //若是栈空 则将字符存进去
         else
             f = Precede(op.top(), str[i])   //判断两符号的优先关系
         switch f
                case:'>' 
                        从树栈node出栈两个结点存入a,b中
                        调用CreateExpTree函数建立数二叉树p并入栈
                        i--
                        break
                case '<':op.push(str[i]); break;  //优先级比栈顶元素高
        case '=':op.pop(); break; 
end while    

while 运算符栈op中不为空且栈node也不为空   
              从树栈node出栈两个结点存入a,b中
              调用CreateExpTree函数建立数二叉树p并入栈          

end while



double EvaluateExTree(BTree T)
定义浮点数sum,b,m
创建double类型的栈 num表示将每一次计算结果存进去以及取出来
创建字符栈 s表示存入的数据有运算符有数
创建树类型的栈 node表示每次取数的结点
while T
     将每一个结点的数据一个个存入s,以及将结点T存入node中
end while
while s不为空
    if s的栈顶元素为数字 then
      将字符转化为数存入num中
    else //为运算符时候
       sum=num的栈顶元素
        num去栈顶元素
        b=num的栈顶元素
        num去栈顶元素
        switch s的栈顶元素
            case '+':sum += b; break;
        case '-':sum -= b; break;
        case '*':sum *= b; break;
            case '/':
         if b等于0  
                输出divide 0 error!\n
                关闭程序
            else sum /= b;
            end if 
            break    
    s.pop();
    num.push(sum);      
返回sum

2.1.2代码截图



2.1.3本题PTA提交列表说明。

  • Q1:一开始提交时候是为多种错误,里面有段错误有答案错误
  • A1:当我在判断了栈顶优先级高的时候,搞错了要从node中弹出两个根结点出来,我只弹出一个致使出现错误,主要仍是老师给咱们讲过了,还给了咱们建树的ppt的伪代码,而后才会打...
  • Q2:后来只对了五分的状况,是只对了除0错误这个测试点,至于其余两个主要测试点都没过
  • A2:这个改了特别久,改了好几天,一直没发现错误,后来发现,原来在创建这棵树的时候,判断符号优先级别时,当Precede返回大于号时候,还要i减一,否则在后面i在加一可能不能一直判断栈顶元素与当前元素的优先级谁高

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

二叉树叶子结点的带权路径长度指:叶子结点的权重路径长度。本题要求算出二叉树全部叶子结点的带权路径长度和。 以下面的二叉树:

2.2.1设计思路(伪代码)

主要说建树函数和计算权值的函数
BiTree create(string str, int n) 
创建新的树节点 BT
if str[n] 等于字符# 返回NULL end if
if n>str.size() - 1 返回NULL end if
BT->data = str[n];                                                                                       
BT->lchild = create(str, 2 * n); //递归建树
BT->rchild= create(str, 2 * n+1);
返回 BT;


void GetWPL(BiTree bt,int h,int&wpl)
if bt等于NULL 返回 
end if 
if bt左右孩子不空  
    wpl=wpl+(bt->data-'0')*h;
end if 
    GetWPL(bt->lchild,h+1,wpl);
    GetWPL(bt->rchild,h+1,wpl);

2.2.2代码截图

2.2.3本题PTA提交列表说明。

  • Q1:第一次和第二次的只有五分的测试点过了,而后也百度过了也是没出来
  • A1:直到正确答案出来我再看一下原来代码,发现错误的是在计算权值的函数中,再对左右子树的搜索中,我是将对左右子树的遍历放在判断是否为叶子结点里面,致使其实没对整颗二叉树进行遍历
  • Q2:再第三四次的提交中,仍是只有五分,后来上课看了老师的作题后发现了错误
  • A2:在传参时候应该先传进去0,而不是传进去1,若是是1的话会致使层数多1,而致使最后结果错误
  • Q3:在其中还有就是有时devc有跳错
  • A3:递归口设置的不对,致使最后到了空时候还进行操做致使出错
    ***node

    2.3.题目1:7-2 根据后序和中序遍历输出先序遍历

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

2.3.1设计思路(伪代码)

#include<iostream>
using namespace std;
int in[31], post[31];
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;



BiTree Build(int *in, int *post, int n)//第一个参数是中序序列的起始位置,第二个参数是后序序列的起始位置,n是长度 

    定义len, *p
    if n <= 0 then//若是长度小于等于0,直接返回便可 
        return NULL
        end if 
    p = in;
    for pto in+n  //少打了一个+n
        if  *p == *(post + n - 1) then break
                end if
         enf for
    创建新结点T
    T->data = *p
    len = p - in;
    T->lchild = Build(in, post, len);
    T->rchild = Build(p + 1, post + len, n - len - 1);
    返回T



void PreOrder(BiTree T)

    if T不为空 then 
        输出 T->data;
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    end if 
    return




int main()

    定义 n, i=0分别表示数组长度和循环变量;
    BiTree T;//只须要定义,不须要赋值->[BiTree T = new BiTNode;] 
    输入 n
    for i to n do 
        输入 post[i]
         end for
    for i to n do 
        输入 in[i]
         end for
    T = Build(in, post, n)
    输出"Preorder:"
    PreOrder(T)
    return 0

2.3.2代码截图

2.3.3本题PTA提交列表说明。

  • Q1:多种错误中有答案错误还有格式错误
  • A1:格式错误能够解决,那个答案错误,一开始觉得应该将p赋值放在循环外,但这个没影响啊,后来是循环条件错了,忘了in是用指针来的,应该p小于in+n
  • Q2:再改了循环条件后再次提交就过了一个测试点
  • A2:对于形参n,再建立右子树时候错误,原本是写n-len,后来调试一点点画图一点点看时候,发现应该还要再减一才正确

三、阅读代码

3.1 题目 :判断一棵树是不是另外一棵树的子树


3.2 解题思路

  • 1.树的后序遍历的最后一个数必定是树的根节点,因此根据后序和中序利用递归建好树
  • 2.再用队列层次输出ios

    3.3 代码截图



3.4 学习体会

  • 1. 他经过中序和后序来建树和我不太同样,看起来比我方便多了,还多了个形参
  • 2.在层次输出那一块的代码,我在打pta的那道题时候,打不出来,而后他用了队列的方法,这个一开始是没想到的,用队列作的确更快,原本我想用递归的
相关文章
相关标签/搜索