数据结构 实验报告11

一、实验目的和要求

目的:熟悉后序线索二叉树并实现后序遍历

要求:

(1)创建二叉树。

(2)转换为后序线索二叉树。

(3)实现后序遍历的非递归算法。
二、实验环境

编译器:Vscode +DevC++

系统:Windows10

CPU:i5-8265U@1.60GHz
三、实验内容

(1)创建二叉树。

(2)转换为后序线索二叉树。

(3)实现后序遍历的非递归算法。
四、实验过程
4.1 任务定义和问题分析

1.创建二叉树

沿用之前使用二叉树创建模板;(若兼容后序线索二叉树的话)

或者重新创建二叉树类(后序线索二叉树需要其他辅助变量)

      2.转换成后序线索二叉树

            在转换时只需要按照后序遍历,(需要记录当前结点的前驱)逐个将空指针利用起来

      3.实现后序遍历的非递归算法

            需要经过多重循环,首先通过while找到最左结点,然后遍历后继……
4.2 数据结构的选择和概要设计

必是选择链式结构;

在创建树时,使用扩展先序序列创建;

        详细设计

第一尝试:

      首先将之前写的二叉树类扩展了,添加了rtag和ltag变量用于识别指针是否指向儿子;其次添加了一个全局结点指针变量,用于实现对前驱的记录

      接着对后序遍历进行修改

然后就是添加函数  使其能够进行对后序非递归遍历

在编写此方面代码时就出现了问题

我的第一版函数是如下操作的

      1.先找到第一个结点(最左的结点)

      2.再遍历其后继

      3.然后再找到当前结点的最左儿子

      4.重复2,3操作直到结点为空

在实际面对下面二叉树时,就出现了预想不到的事情:

进入了死循环————CDBCDB

下面展示后序线索(绿色指向前驱,红色指向后继):

不难看出再程序寻到B时对A的左子树操作就完成了,需要去操作A的右子树,然而对于非递归遍历来说,我们现在就是过了河的卒,无法回头,在执行到B时没有操作能够支持我们去操作A的右子树

故而 添加辅助空间:父亲指针;

并在创建树时,记录每个结点的父亲结点

在执行非递归后序遍历时,操作如下

    找寻到以当前结点为根的树的后序遍历的起始节点
    按次序找寻后继并输出数据
    判断是否达到根结点(是:输出数据并结束遍历;否:进行下一步)
    逐层向上返回,并输出数据,直到是从当前左子树返回为止
    去访问右孩子
    回到第一步

五、测试及结果分析
5.1 实验数据

 
5.2 结果及分析

正确实现了二叉树向后序线索树的转换

并实现了后序遍历的非递归输出
六、实验收获

熟悉了线索二叉树

 
七、参考文献

数据结构-线索二叉树(后序线索二叉树及遍历)

《大话数据结构》
八、附录(源代码)

    /*
     * @Descripttion:
     * @version:
     * @Author: Nice_try
     * @Date: 2020-05-26 09:10:57
     * @LastEditors: Nice_try
     * @LastEditTime: 2020-05-26 17:59:12
     */
     
    #include <iostream>
     
    #include<cstdio>
     
    #include<algorithm>
     
    #include<typeinfo>
     
    using namespace std;
     
    #define Link 0   //表示该节点有非空孩子节点
     
    #define Thread 1 //表示该节点有后续节点(对于右子树来说)
     
    #define MAXSIZE 100
     
     
     
    template <class T>
     
    struct BT_Thread_Node
     
    {
     
        T Data;
     
        BT_Thread_Node *Left_Child;
     
        BT_Thread_Node *Right_Child;
     
        BT_Thread_Node *Parent; //指向该节点的父母节点
     
        int Ltag;
     
        int Rtag;
     
    };
     
     
     
    template <class T>
     
    class Thread_Binary_tree
     
    {
     
    private:
     
        BT_Thread_Node<T> *Tree;
     
        BT_Thread_Node<T> *Pre_Node;
     
        BT_Thread_Node<T> *BT_Node_Stack[MAXSIZE];
     
        int Top;
     
        int Create_Thread_BTree(BT_Thread_Node<T> *&Tree, BT_Thread_Node<T> *Parent);
     
        void PostOrder_Thread_Op(BT_Thread_Node<T> *&Tree);
     
        void _PostOrder_Op(BT_Thread_Node<T> *&Tree);
     
     
     
    public:
     
        Thread_Binary_tree();
     
        ~Thread_Binary_tree();
     
        void PostOrder_Thread();
     
        void _PostOrder();
     
    };
     
     
     
    template <class T>
     
    int Thread_Binary_tree<T>::Create_Thread_BTree(BT_Thread_Node<T> *&Tree, BT_Thread_Node<T> *Parent_Node)
     
    {
     
        T Data;
     
        cin >> Data;
     
        if(Data=='#'||Data==-1)
     
            Tree = NULL;
     
        else
     
        {
     
            Tree = new BT_Thread_Node<T>;
     
            Tree->Parent = Parent_Node; //指向父母节点
     
            Tree->Data = Data;
     
            Tree->Ltag = Link;
     
            Tree->Rtag = Link;
     
            Create_Thread_BTree(Tree->Left_Child, Tree); //Tree是孩子的父母节点
     
            Create_Thread_BTree(Tree->Right_Child, Tree);
     
        }
     
        return 1;
     
    }
     
     
     
    template <class T>
     
    void Thread_Binary_tree<T>::PostOrder_Thread_Op(BT_Thread_Node<T> *&Tree)
     
    {
     
        if (Tree == NULL)
     
            return;
     
     
     
        PostOrder_Thread_Op(Tree->Left_Child);  //左
     
        PostOrder_Thread_Op(Tree->Right_Child); //右
     
     
     
        if (Tree->Left_Child == NULL) //根
     
        {
     
            Tree->Left_Child = Pre_Node;
     
            Tree->Ltag = Thread;
     
        }
     
        if (Pre_Node != NULL && Pre_Node->Right_Child == NULL)
     
        {
     
            Pre_Node->Right_Child = Tree;
     
            Pre_Node->Rtag = Thread;
     
        }
     
     
     
        Pre_Node = Tree;
     
    }
     
     
     
    template <class T>
     
    void Thread_Binary_tree<T>::_PostOrder_Op(BT_Thread_Node<T> *&Tree)
     
    {
     
        if (Tree == NULL)
     
            return;
     
     
     
        BT_Thread_Node<T> *Cur_Node = Tree;
     
        Pre_Node = NULL;
     
        while (Cur_Node != NULL)
     
        {
     
            while (Cur_Node->Left_Child != Pre_Node) //change,找到起始节点(在左树的最左边)
     
            {
     
                Cur_Node = Cur_Node->Left_Child;
     
            }
     
     
     
            while (Cur_Node != NULL && Cur_Node->Rtag == Thread) //按线索找到次树节点
     
            {
     
                BT_Node_Stack[++Top] = Cur_Node;
     
                cout << Cur_Node->Data << " ";
     
                Pre_Node = Cur_Node; //每次访问节点后,PreNode更新
     
                Cur_Node = Cur_Node->Right_Child;
     
            }
     
     
     
            if (Cur_Node == Tree) //如果当前节点为根节点,说明遍历完成
     
            {
     
                BT_Node_Stack[++Top] = Cur_Node;
     
                cout << Cur_Node->Data << " ";
     
                return;
     
            }
     
     
     
            while (Cur_Node != NULL && Cur_Node->Right_Child == Pre_Node) //当前节点的右孩子节点刚好上次遍历,说明该袖珍树只差根就遍历完成
     
            {
     
                BT_Node_Stack[++Top] = Cur_Node;
     
                cout << Cur_Node->Data << " ";
     
                Pre_Node = Cur_Node;
     
                Cur_Node = Cur_Node->Parent; //访问袖珍树后回到上一层
     
            }
     
     
     
            if (Cur_Node != NULL && Cur_Node->Rtag == Link) //回到上一层后,先访问右孩子
     
            {
     
                Cur_Node = Cur_Node->Right_Child;
     
            }
     
        }
     
    }
     
     
     
    template <class T>
     
    Thread_Binary_tree<T>::Thread_Binary_tree() : Pre_Node(NULL), Top(-1)
     
    {
     
        Create_Thread_BTree(Tree, NULL);
     
    }
     
     
     
    template <class T>
     
    Thread_Binary_tree<T>::~Thread_Binary_tree()
     
    {
     
        while (Top != -1)
     
        {
     
            delete BT_Node_Stack[Top];
     
            Top--;
     
        }
     
    }
     
     
     
    template <class T>
     
    void Thread_Binary_tree<T>::PostOrder_Thread()
     
    {
     
        PostOrder_Thread_Op(Tree);
     
    }
     
     
     
    template <class T>
     
    void Thread_Binary_tree<T>::_PostOrder()
     
    {
     
        _PostOrder_Op(Tree);
     
    }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/799305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每天学习一个Linux命令之curl

每天学习一个Linux命令之curl 在Linux系统中&#xff0c;有很多有用的命令可以帮助我们与网络进行交互。一个非常常用的命令是curl&#xff0c;它是一个功能强大的工具&#xff0c;可用于发送、接收和处理各种网络请求。本文将详细介绍在Linux下使用curl命令的各种选项及其用法…

如何理解图像处理领域的病态问题(ill-posed problem)

ill-posed problem&#xff0c;我们可以理解为病态问题或者不适定问题。在本文中&#xff0c;统一成为不适定问题。 在讨论不适定问题&#xff08;ill-posed problem&#xff09;之前&#xff0c;我们先来看一下什么叫适定性问题&#xff08;well-posed problem&#xff09;。…

如何明确的选择IT方向?

一、明确目标 作为初学者&#xff0c;先树立自己目标&#xff0c;找到自己感兴趣的IT行业&#xff0c;IT行业分很多种&#xff0c;听的最多次的无非不就是web前端工、程序员、后端、大数据、网络运维等。学习知识也是为了找到更好的工作&#xff0c;所以我建议先去boss直聘、五…

浅谈Mysql(四)——Mysql知识补充

一、mysql什么时候会锁表 MySQL中的查询语句通常不会锁表&#xff0c;因为查询操作只读取数据而不修改数据。然而&#xff0c;当执行某些特定的查询语句或者在特定情况下&#xff0c;MySQL可能会对表进行锁定以保证数据的一致性和完整性。以下是几种可能导致表锁定的情况&#…

目标检测标签分配策略,难样本挖掘策略

在目标检测任务中&#xff0c;样本的划分对于模型的性能具有至关重要的影响。其中&#xff0c;正样本指的是包含目标物体的图像或区域&#xff0c;而负样本则是不包含目标物体的图像或区域。然而&#xff0c;在负样本中&#xff0c;有一部分样本由于其与正样本在特征上的相似性…

jest单元测试——项目实战

jest单元测试——项目实战 一、纯函数测试二、组件测试三、接口测试四、React Hook测试&#x1f4a5; 其他的疑难杂症另&#xff1a;好用的方法 &#x1f31f; 温故而知新&#xff1a;单元测试工具——JEST 包括&#xff1a;什么是单元测试、jest的基本配置、快照测试、mock函数…

机器学习工作流

本文的目的是演示如何构建一个相对完整的机器学习工作流 1.首先对工程进行基本的参数配置 # 进行建模基本配置 SCORE_EVA roc_auc random_state_clf 1 n_jobs 4 cv_split StratifiedKFold(n_splits5, shuffleTrue, random_state1) cv_split2 StratifiedKFold(n_splits5, …

(013)window的Idea运行程序 Amazon java.nio.file.AccessDeniedException

解决方法一 在资源管理器中删除该目录&#xff0c; 在程序中使用代码&#xff0c;重新建立该目录&#xff1a; if (!FileUtil.exist(destinationPath)){FileUtil.mkdir(destinationPath); }解决方法二 JDK 的版本有问题&#xff0c;换个JDK。 解决方法三 网络不好&#xf…

「39」打造专业流畅的直播特效转场……

「39」工作室模式 打造专业流畅的直播特效转场体验 工作室模式是OBS软件里的一个特殊功能,用于后期直播过程中追求直播效果的用户,才会使用此功能。 该功能意在更加平滑,使用模板信息变化的过渡效果。主要用在赛事比分、活动抽奖、直播时需要经常更改的场景和内容,以及片…

Spring之底层架构核心概念解析

你好&#xff0c;我是柳岸花开。 在当今快速发展的软件开发领域&#xff0c;各种技术层出不穷&#xff0c;但有一项技术以其卓越的设计、灵活的配置和广泛的应用&#xff0c;始终屹立在开发者的工具箱中——这就是Spring框架。自2003年首次发布以来&#xff0c;Spring已经成为J…

Android 11属性系统初始化流程

在init进程启动的第二阶段&#xff0c;调用PropertyInit 对属性系统进行初始化 int SecondStageMain(int argc, char** argv) {//省略PropertyInit();//省略 }PropertyInit函数在system\core\init\property_service.cpp 中实现 void PropertyInit() {//省略mkdir("/dev/…

opencv x86(32位) windows下vs2019编译问题

opencv x86(32位) windows下vs2019编译相关资料很多&#xff0c;都特别受用。例如 - https://blog.csdn.net/m0_59025104/article/details/134109081 - https://blog.csdn.net/sements/article/details/108410470 但是&#xff0c;自己编译时候仍遇到一些问题&#xff0c;例如&…

智能网联汽车自动驾驶数据记录系统DSSAD数据元素

目录 第一章 数据元素分级 第二章 数据元素分类 第三章 数据元素基本信息表 表1 车辆及自动驾驶数据记录系统基本信息 表2 车辆状态及动态信息 表3 自动驾驶系统运行信息 表4 行车环境信息 表5 驾驶员操作及状态信息 第一章 数据元素分级 自动驾驶数据记录系统记录的数…

【GameFi】 链游 | Brilliantcrypto点火活动

活动&#xff1a;https://app.galxe.com/quest/brilliantcrypto/GCt8wthq2J Brilliantcrypto点火活动正在Galxe上进行 &#x1f389; 活动时间&#xff1a;2024/04/06 12:00 ~ 2024/05/04 12:00 奖励总价值1200美元的MATIC 完成任务並在Brilliantcrypto Galxe Space上赚取积分。…

【数据结构与算法】:快速排序和冒泡排序

一&#xff0c;快速排序 快速排序是一种比较复杂的排序算法&#xff0c;它总共有4种实现方式&#xff0c;分别是挖坑法&#xff0c;左右"指针"法&#xff0c;前后"指针"法&#xff0c;以及非递归的快速排序&#xff0c;并且这些算法中也会涉及多种优化措施…

Docker是一个开源的应用容器引擎

Docker是一个开源的应用容器引擎&#xff0c;它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口。Docker技术的…

zdpdjango_materialadmin使用Django开发一个Material风格的后台管理系统

启动项目 同样地&#xff0c;还是先看看代码&#xff1a; 将项目启动起来&#xff1a; 浏览器访问&#xff1a;http://localhost:8000/ 代码初步优化 首先是将admin_materal提到本地来&#xff1a; 移除掉第三方依赖&#xff1a; pip uninstall django-admin-materi…

sqlserver2014安装与老版本卸载

本篇博客只提供安装包 安装与卸载难度较低&#xff0c;不做赘述 并不是说一定要卸载才能安装&#xff0c;灵活掌握&#xff0c;如果实际场景需要清理老版本sqlserver那么选择卸载 一、下载 下载地址 sqlserver2014官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘 二、卸载…

移动平台相关(安卓)

目录 安卓开发 Unity打包安卓 ​编辑​编辑 BuildSettings PlayerSettings OtherSettings 身份证明 配置 脚本编译 优化 PublishingSettings 调试 ReMote Android Logcat AndroidStudio的调试 Java语法 ​编辑​编辑​编辑 变量 运算符 ​编辑​编辑​编辑​…

面向低碳经济运行目标的多微网能量互联优化调度matlab程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 运用平台 matlabgurobi 程序简介 该程序为多微网协同优化调度模型&#xff0c;系统在保障综合效益的基础上&#xff0c;调度时优先协调微网与微网之间的能量流动&#xff0c;将与大电网的互联交互作为备用…