第五章学习小结

这一次我们来聊聊“判断树是否同构”这道题吧!

一如既往的前情提要如下:

看到题目后,我们第一步是审题。可以观察其文字说明以及输入输出形式,初步构思我们的操作。

在清楚题目想让我们做什么的基础上,我们就大致把握了解题的思路了。

这道题的解题思路十分清晰,思路如下:

(1)表示二叉树(定义)

(2)建立二叉树(输入数据)

(3)判断二叉树同构

逐点突破

对于(1),我们可以考虑完全二叉树的形式,以结构体数组的方式存储数据。因为有左右孩子,所以定义三个量。

定义如下:

#include<iostream>
using namespace std;
#define MaxTree 10
#define ElementType char
#define Null -1//注意:因为下面没有定义左右孩子的指针,所以要另行定义Null 
typedef int Status;
typedef struct TreeNode//考虑以完全二叉树的形式 
{
    ElementType data;
    int Left;
    int Right;
}Tree;
Tree T1[MaxTree],T2[MaxTree];//定义树 

接下来就到了输入数据的环节,这需要我们构建“建立二叉树”的函数,函数如下:

int BuildTree(Tree T[])//建立二叉树 
{
    int i,N,check[MaxTree],Root=Null;
    char cl,cr;//以字符形式输入 
    cin>>N;//输入总数目 
    if(N)//寻找根节点的方法:先将check初始化为0,。当出现左孩子和右孩子时,将check标为1,最后遍历check,为0的即为根节点 
    {
        for(i=0;i<N;i++)
            check[i]=0;
        for(i=0;i<N;i++)
        {
            cin>>T[i].data>>cl>>cr;
            if(cl!='-')
            {
                T[i].Left=cl-'0';
                check[T[i].Left]=1;
            }
            else
                T[i].Left=Null;
            if(cr!='-')
            {
                T[i].Right=cr-'0';
                check[T[i].Right]=1;
            }
            else
                T[i].Right=Null;
        }
    }
        for(i=0;i<N;i++)//寻找根节点 
        {
            if(!check[i])
            {
                Root=i;
                break;//找到根节点,退出循环 
            }
        }
    return Root;//返回根节点 
}

注意寻找根节点的奇妙方法。

对于(3),我们可另行构建“判断二叉树是否同构”的函数,注意考虑判断同构的多种情况(很多很多种)!

函数如下:

Status Isomorphic(int Root1,int Root2)//判断二叉树是否同构 
{
    if((Root1==Null)&&(Root2==Null))
        return 1;
    if(((Root1==Null)&&(Root2!=Null))||((Root1!=Null)&&(Root2==Null)))
        return 0;
    if(T1[Root1].data!=T2[Root2].data)
        return 0;
    if((T1[Root1].Left==Null)&&(T2[Root2].Left==Null))
        return Isomorphic(T1[Root1].Right,T2[Root2].Right);
    if(((T1[Root1].Left!=Null)&&(T2[Root2].Left!=Null))&&((T1[T1[Root1].Left].data)==(T2[T2[Root2].Left].data)))
        return (Isomorphic(T1[Root1].Left,T2[Root2].Left)&&Isomorphic(T1[Root1].Right,T2[Root2].Right));
    else
        return (Isomorphic(T1[Root1].Left,T2[Root2].Right)&&Isomorphic(T1[Root1].Right,T2[Root2].Left));
}

根据习惯,我们把各函数写在前面,而把主函数置于其后。注意,主函数即思路框架的具体化:

int main()
{
    int Root1,Root2;
    Root1=BuildTree(T1);
    Root2=BuildTree(T2);
    if(Isomorphic(Root1,Root2))
        cout<<"Yes";
    else
        cout<<"No";
    return 0;
}  

锵锵~ 题目就这样解出来啦!这道题目的思路十分简单,不过要求在细节方面考虑周全,是很不错的基础题呢!

好啦,接下来就到了日日反思环节:

有了之前的一些基础,感觉树的内容比较好掌握。但还是需要大量的辅助学习。在舍友的推荐下,慕课网成为了我的第二课堂(待会儿分享链接)。慕课的视频在课下给予了我极大的帮助,例如这道题目,也是慕课老师引导着我一步步写出来的,在此对于线上工作者表示感谢。

最近的学习状态还好,课上认真听讲,课下及时复习。只不过因为近两个星期都是考试周,缺了许多练习代码的时间。没关系,会补上的!

最后给自己鼓励吧,下星期一的小测要加油!

 

posted @ 2019-05-03 11:03  Haylie  阅读(192)  评论(3编辑  收藏  举报