DS博客作业05--树

1.本周学习总结(0--2分)

1.思维导图

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

  • 本周学习了树和二叉树这一结构,对于之前的结构来说,我觉得难了很多,首先这个结构有孩子结点,兄弟结点,双亲结点等, 首先从创建树的结构来说就复杂了很多,在对树的很多操作中用到了很多递归的算法,这对于本来之前递归算法就不太理解的我来说挺难的,而且一旦程序写错了,递归算法很不容易发现错误,所以在写树的相关程序的时候,最重要的我觉得还是整个思路的问题,有些递归算法不太容易想出来,而一旦想出来问题就变得简单很多了。

  • 二叉树有先序,中序,后序遍历等遍历树的方法,其中还有相关的转换,这个问题感觉很难,理解三种的转化还挺容易,但是代码的实现特别难写...感觉要看好多好多遍才能记住...总结就是这章的知识点挺多的

2.PTA实验作业(6分)

2.1 6-4 jmu-ds-表达式树 (25 分)

2.1.1设计思路(伪代码)

void InitExpTree(BTree &T,string str)  //建表达式的二叉树
{
        定义一个栈s存放数字 
        定义一个栈op 存放运算符 
        ‘#’进op栈;
        while遍历str 给树结点赋值 
        {
            If str[i]为数字
            {
                新建树结点T=new BiTNode;
                T->data=str[i++];T的左右孩子都置为空
                T入s栈;
            }
            else是运算符
            {
                switch调用precede函数比较op栈顶和str[i]
                {	
                    case'<':str[i++]入栈op
                    case'=':op栈出栈 
                    case'>':
                        新建结点T,T->data=op.top()
                        T->rchild=s.top();s栈出栈
                        T->lchild=s.top();s栈出栈
                        新建的T结点入s栈
                        op栈出栈
                }
        } 
        while(op栈顶元素不是'#') //把树结点的关系连起来 
        { 
            新建结点T; 
            T->data=op.top();op栈出栈
            T->rchild=s.top(); s栈出栈 
            T->lchild=s.top();s栈出栈 
            T结点进s栈
        }
}
double EvaluateExTree(BTree T)计算表达式树
{
        定义a,b
        if  树T不空
            if 左右孩子都为空 return T->data-'0';
            a=EvaluateExTree(T->lchild)
            b=EvaluateExTree(T->rchild)
            switch T->data
                case'+':return a+b
                case'-':rerurn a-b
                case'*':return a*b
                case '/':
                    if b==0 输出divide 0 error!
                    else return a/b
}

2.1.2代码截图




2.1.3本题PTA提交列表说明

  • Q1:这题刚开始没有什么思路,不明白具体怎样把表达式建成树
  • A1:查了一下思路,主要是建两个栈s和op分别用来存放数字和运算符,遇到数字就赋给树结点T然后入s栈,遇到运算符和之前栈的题目差不多,要比较与op栈顶的符号的先后级,小于直接进op栈,大于则要先把op栈顶的运算符与s栈中元素的关系建立,然后再将T进s栈。等于直接op栈出栈,如此建立树,然后计算输出。

2.2.题目2:7-1 还原二叉树 (25 分)

2.2.1设计思路(伪代码)

#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
定义字符型数组 str1[110],str2[110];
int main()
{
    int n;
    输入结点个数n;
    输出str1 str2;
    输出二叉树高度
    return 0;
}
int dfs(char a[],char b[],int m)
{
    if m==0
        return 0;//没有节点,为空树
    end if
    int i;
    for i=0 to i<m
    {
        if b[i]==a[0] //找到根节点在中序的位置
             break;
    }
    end for
    int c=dfs(a+1,b,i)+1;//左子树的深度
    int d=dfs(a+i+1,b+i+1,m-i-1)+1;//右子树的深度
    int h;
    if c>d
	h=c++;
    else
	h=d++;
    return h;
}

2.2.2代码截图(注意,截图,截图,截图。不要粘贴博客上。)


2.2.3本题PTA提交列表说明。

  • Q1:这题的主要问题就是思路上还原二叉树厅容易,但是在代码实现上不是很容易想到,运用了递归算法
  • A1:主要还是对递归算法不是很熟悉,先找到树根,中序序列的树根前面的字符串是其左子树,后面是右子树。再将左子树和右子树的序列分别作为一棵树进入递归,对其重复找出树根和左右子树的处理,每次记录下当前左右子树的深度,最后返回最大深度

2.3.题目3:7-5 jmu-ds-输出二叉树每层节点 (22 分)

2.3.1设计思路(伪代码)

main函数和建树函数CreatTree(string str, int &i)
void LevelOrder(BinTree BT)  //层次遍历
{
	定义BinTree型队列qt;
	int level,flag;
	定义BinTree结构体curNode,lastNode;
	curNode=lastNode=BT;
	if BT==NULL 
      		输出NULL
      		return ;
	else
     		BT进队
     	while(队qt不为空)
    	{
        		if  curNode==lastNode 
        		{
            			level++;
            			用flag控制换行
            			lastNode=qt.back();
        		}
		end if
        		curNode=qt.front();     
        		输出curNode->Data
        		if  curNode->Left不为空
            		curNode->Left进队qt
        		if  curNode->Right非空
            		curNode->Right进队qt
       		qt队出队
    	}
}

2.3.2代码截图(注意,截图,截图,截图。不要粘贴博客上。)



2.3.3本题PTA提交列表说明。

  • 实际上是二叉树的层次遍历,先将根结点A入队,然后出队,访问A,将A的左右孩子BC入队,出队,然后再访问BC的左右孩子,按照以上方法,入队,出队,访问并将他的左右孩子入队,直到队列为空。

3、阅读代码(-2--2分)

3.1 题目寻找重复的子树

给定一棵二叉树,返回所有重复的子树。对于同一类的重复子树,你只需要返回其中任意一棵的根结点即可。
两棵树重复是指它们具有相同的结构以及相同的结点值

下面是两个重复的子树:

3.2 解题思路

通过map记录每颗子树先序遍历或者后序遍历的结果, 找到所有遍历结果相同的子树。

3.3 代码截图

3.4 学习体会

  • 这题的话还是用到的递归算法,还有hash数组,同时结构不同的子树单纯的后序或是先序遍历可能结果一样,可以做一下特殊处理,即空树的遍历结果为某个特殊字符,这样一颗树的遍历结果就被唯一限定了
  • 看了挺多力扣上的题,大部分其实都用到很巧妙的递归算法,代码很简练,所以在递归上的思路和理解运用上还要多多练习。
原文地址:https://www.cnblogs.com/zyxaa/p/10886062.html