第五章题解

第五章 树和二叉树

本章我们重点学习了树和二叉树的定义、二叉树的性质、存储结构、二叉树的先中后序遍历。简略的学习了树和森林的存储结构、遍历,大致讲解了哈夫曼树的基本感念。在学习过程中,建树和二叉树的遍历对我来讲比较难。建树可以用顺序存储也可以用二叉链表存储,二叉树的遍历可以用递归实现也可以用非递归实现。下面主要讲讲我在PTA做题过程的一些感想和思路。

List Leaves

这道题的思路很简单: 构造二叉树的结点结构体、建立二叉树、利用队列输出叶子结点

第一步 构造二叉树的结点结构体

由于这道题的数据N只在10以内,所以我用了顺序存储结构。

1 typedef struct{ //定义二叉树的结点结构
2     int Left;
3     int Right;
4 }BiTreenode;

第二步 建立二叉树

这里要注意的问题有:

1.输入的是char类型数据,因此为了标号方便要将其ASCII码减去0的ASCII码

2. 要定义一个数组root(bool类型或者int类型),以利于标记这个结点的子树是否是根结点

int Buildtree(BiTreenode T[]){ 

    bool root[10]={false};
    int n,i;
    char x,y;
    cin>>n;

    for(i=0;i<n;i++){

        cin>>x>>y;
        if(x!=‘-‘){//判断左儿子是否为空,若不为空则左二子不为根结点,赋值为true
            T[i].Left=x-‘0‘;
            root[T[i].Left]=true;
        }
        else T[i].Left=-1;

        if(y!=‘-‘){ //判断右儿子是否为空,若不为空则右儿子不为根结点,赋值为true
            T[i].Right=y-‘0‘;
            root[T[i].Right]=true;
        }
        else T[i].Right=-1;
    }    

    for (int i=0; i<n; i++){//寻找根结点 ,当 root[]为-1时该式子成立,返回i的下标,即根节点的下标
        if(!root[i])
        return i;
    }
}

第三步 利用队列输出叶子结点

利用队列的好处是先进先出,而且在push一个数据之后就将它pop出来直接对它的左右孩子进行比较,非常方便

void OrderTree(BiTreenode T[],int x){//利用队列输出叶子结点 

    queue<int> q;
    int k;
    q.push(x);//将根节点入队
    while(!q.empty()){//当队列不为空的时候,继续执行循环 

        int tmp=q.front();//访问队列的首结点,也就是将最早入队的结点的下标赋值给tmp 

        if(T[tmp].Left!=-1) //若该节点的左儿子不为空,则将它压入队列中
        q.push(T[tmp].Left);
        if(T[tmp].Right!=-1)//若该节点的右儿子不为空,则将它压入队列中
        q.push(T[tmp].Right); 

        q.pop();   //弹出队列中的第一个元素
        if(T[tmp].Left==-1 && T[tmp].Right==-1){ //若该结点的左儿子和右儿子均为空,则该结点为叶子结点,输出该叶子结点
            cout<<tmp;
            if(!q.empty()) //若队列不为空,则输出的不是最后一个叶子结点,在输出空格
            cout<<" ";
        }    

    }
}    

树的同构

这道题的思路主要是:构造结点结构体、构造二叉树、将两棵二叉树进行比较。

第一步 构造结点结构体

这道题我也是用了顺序存储结构,与上一道题不一样的地方是,这道题需要输入字符域element。

typedef struct Treenode{
    char element;
    int left;
    int right;
}Treenode;

第二步 构造二叉树

与上一道题目大同小异,主要是这里需要构造两棵树。

第三步 将两棵二叉树进行比较

这个步骤有些复杂,主要是在比较过程中要把逻辑思路搞清楚。

1. 两棵树都是空树的情况

2. 其中一棵树是空树的情况下

3. 根节点都存在但数值不同

4. 左子树不存在,则递归判断右子树

5. 左子树同时不空则无需交换左右子树,否则交换左右子树

bool Comparetree(int R1,int R2){

    if( (R1==Null) && (R2==Null) )
        return true;//两棵树都为空,则同构 

    if( ((R1==Null) && (R2!=Null)) || ((R1!=Null) && (R2==Null)) )
        return false;//两棵树中有一棵为空,另外一棵树不为空,则不同构

    if( T1[R1].element!=T2[R2].element )
        return false;//若两棵树都不为空,但树根的值不相同,则不同构 

    if( (T1[R1].left==Null) && (T2[R2].left==Null) )
        return Comparetree( T1[R1].right,T2[R2].right );//两棵树都不为空,根的值相同。若左子树都为空,则是否同构取决于右边,递归调用右子树的判别 

    if( ((T1[R1].left!=Null) && (T2[R2].left!=Null)) && ((T1[T1[R1].left].element)==(T2[T2[R2].left].element)) )
        return(Comparetree(T1[R1].left,T2[R2].left) && Comparetree(T1[R1].right,T2[R2].right));//左子树是否同时不空,若同时不空则无需交换左右子树 

    else return (Comparetree(T1[R1].left,T2[R2].right) && Comparetree(T1[R1].right,T2[R2].left));
};

目标总结:

完成了三分之二的题解,比上次进步一点。

下次目标:

完成所有题解。

原文地址:https://www.cnblogs.com/butterboy/p/10810514.html

时间: 2024-11-02 10:16:51

第五章题解的相关文章

算法&lt;初级&gt; - 第五章 递归与动规相关问题(完结)

算法<初级> - 第五章 递归与动规相关问题(完结) <一>递归和动态规划 暴力递归 转化为规模缩小了的同问题的子问题 - 时间复杂度O(2n-1) 有明确的边界条件(base case) - 先写base case,再写问题递归的过程 有得到子问题结果后决策过程 不记录每个子问题的解 - 每次求解子问题都交给递归去解决,不会在全局保存子问题的解(与动规形成对比) 动态规划DP 从暴力递归中延申 - 过程中还经历过<记忆化搜索>,相当于暴力递归+cache缓存(用has

《大道至简》第五章读后感

失败的过程也是过程,我觉得这句话很有深意,阅读完大道至简第五章,我又有了很深的感触. 首先是“做过程不是做工程”,过程是为了实现某种目的而经历的一些事情,过程有很多种,虽然经历了某种过程,但不一定能实现某种功能.做完过程的每一个阶段,并不等于做工程.做过程不是做工程的精义,也不是最终目的. 然后是“做过场”,做过场就好像是一种形式一样,做了没必要做的事情,就是浪费时间. 做工程的最终目的是实现客户的要求,工程只是一种实现的途径.最初做开发的前辈们,不用什么工程或者过程,也一样编出了程序,也一样解

大道至简第五章读后感

第五章 失败的过程也是过程 今天照样老师带领着我们阅读了大道至简第五章,阅读了<大道至简>的第五章,这章在前面的基础上又进了一步,有了技术和团队,加上有效的沟通,接下来就要接项目做工程. “虚有其表耳”,本章以<明皇实录>中的一句话来告诉我们一个深刻的道理:不要只求外表,只做形象工程,而是要透过表象,力求实质. 失败了不要紧,没有失败也就找不到自己的不足,也就不会发现自己的问题,更不用谈改进了.我们的前辈们就是在不断的失败中才总结出了“瀑布模型”“螺旋模型”等模型,方便了我们.但是

第五章 电子星球

                   第五章         电子星球   山高高兮.路长长,岁月悠悠兮.转眼空.   镇楼竹: 1. 秀竹一枝自宛然, 莫愁风雨损华年. 几番颠扑呈贞骨, 露重霜寒节更坚. 2. 纤纤凤竹长漓边, 不共山花斗野妍. 时对清流摇倩影, 溪流常伴乐怡然. 3. 坚节何愁风雨多, 晴天朗日更婆娑. 生凉不荫趋炎客, 惹得骚人为咏歌.   咏经典物理.戏现代理论物理: 在山泉水洁如冰, 溅玉飞珠迸有声. 流入大江清浊混, 滔滔何日见澄明.     一.   批驳现代理论

深入浅出Zabbix 3.0 -- 第十五章 Zabbix 协议与API

今天是六.一儿童节,祝小朋友们节日快乐!发完此文就带我家小朋友出去玩耍了. 第十五章 Zabbix 协议与API 本章将介绍和开发相关的Zabbix协议和API的内容,通过对Zabbix协议和API的深入了解,你可以利用Zabbix协议编写客户端程序并将其嵌入的产品或系统中,并将数据发送到Zabbix server,这在无法安装Zabbixagent等程序的场景(例如专用的嵌入式系统)中非常有用.你也可以利用Zabbix API开发自己的业务系统,或灵活的与现有系统整合集成. 15.1 Zabb

Linux与云计算——第二阶段 第五章:存储Storage服务器架设—分布式存储Ceph

Linux与云计算--第二阶段Linux服务器架设 第五章:存储Storage服务器架设-分布式存储Ceph 1 Ceph 配置Ceph集群 Install Distributed File System "Ceph" to Configure Storage Cluster. For example on here, Configure Cluster with 1 admin Node and 3 Storage Node like follows. | +------------

第五章搭建S3C6410开发板的测试环境

第五章本章主要介绍开发板的调试环境的搭建,以及如何将Android系统安装开发板上. 开发板是开发和学习嵌入式技术的主要硬件设备. 尽管可以在PC上开发Linux驱动,然后重新编译成ARM构架的Linux驱动模块,但最终都是要在开发板上进行测试的. 开发板从技术上说与手机类似,包含显示器.键盘.Wi-Fi.蓝牙等模块.开发板可扩展的端口多,容易开发定制的硬件. 第一节S3V6410开发板简介 S3C6410是一款低功耗.高性价比的RISC处理器,它给予ARM11内核,可以广泛应用于移动电话和通用

第五章

第五章 搭建S3C6410开发板的测试环境 ARM构架的开发板可基于X86构架的PC 在CPU指令以及二进制格式上有所不同. 安装串口调试工具 minicon 使用OK6410开发板可以使用其他方法显示Linux驱动程序输出的调试信息.此为串口调试. OK6410开发板自带一个串口.通过串口线与PC连接,linux驱动在输出调试信息的同时,通过串口线将调试信息发送到PC上. 安装.配置和测试minicom: 1.lsmod | grep usbserial 2.apt-get install m

JS复习第五章

第五章 引用类型 一.Object类型 创建object实例的方式有两种. 第一种是使用new操作符后跟object构造函数,如下所示: ver person = new Object( ) ; person.name = “Nicholas” ; person.age = 29 ; 另一种方式是使用对象字面量表示法: var person = { name : “Nicholas”, age : 29 } ; 对象字面量是向函数传递大量可选参数的首选形式. function displayIn