后序线索化二叉树

  • 1.头文件及类型定义
  • 2.线索二叉树结点类型定义
  • 3.函数声明
  • 4.基本操作
    • 4.1 先序建立线索二叉树
    • 4.2 初始化tag
    • 4.3 后序线索化二叉树
      • 4.3.1 访问并建立线索
      • 4.3.2 遍历
      • 4.3.3 后序线索化主过程
    • 4.4 寻找后序前驱
    • 4.5 逆向后序遍历
      • 4.5.1 打印结点
      • 4.5.2 利用后序前驱实现逆向后序遍历
    • 4.6 main函数
    • 4.7 测试
      • 4.7.1 二叉树结构
      • 4.7.2 测试结果
  • 5.小结

1.头文件及类型定义

#include<stdio.h>
#include<stdlib.h>
#define ElemType char

2.线索二叉树结点类型定义

//线索二叉树结点类型定义
typedef struct ThreadNode {ElemType data;                           //数据元素struct ThreadNode* lchild, * rchild;  //左、右孩子指针int ltag, rtag;                            //左、右线索标志//tag=0,表示指针指向孩子;tag=1,表示指针是“线索”,ltag指向前驱,rtag指向后继
}ThreadNode, * ThreadTree;

3.函数声明

/*函数声明*/
void CreateThTree(ThreadTree& T);           //1.先序建立线索二叉树
void InitThread(ThreadTree& T);             //2.初始化tag
void visit1(ThreadNode* q);                 //3-1.访问并建立线索
void PostThread(ThreadTree T);              //3-2.遍历
void CreatePostThread(ThreadTree T);        //3-3.后序线索化主过程
ThreadNode* PreNode(ThreadNode* p);         //4.找到p的前驱结点
void visit2(ThreadNode* p);                 //5-1.打印结点
void RevPostOrder(ThreadNode* T);           //5-2.利用后序前驱实现逆向后序遍历

4.基本操作

4.1 先序建立线索二叉树

/*1.先序建立线索二叉树*/
void CreateThTree(ThreadTree& T) {char c;scanf("%c", &c);if (c == '#')T = NULL;else {T = (ThreadNode*)malloc(sizeof(ThreadNode));T->data = c;CreateThTree(T->lchild);CreateThTree(T->rchild);}
}

4.2 初始化tag

/*2.初始化tag*/
void InitThread(ThreadTree& T) {if (T != NULL) {T->ltag = 0;T->rtag = 0;   //初始化当前树中的tag指针为0,表示还未线索化InitThread(T->lchild);   //递归遍历左子树InitThread(T->rchild);  //递归遍历右子树}
}

4.3 后序线索化二叉树

4.3.1 访问并建立线索

ThreadNode* pre = NULL;     //pre指向当前访问结点的前驱
//3-1.访问并建立线索
void visit1(ThreadNode* q) {if (q->lchild == NULL) {   //左子树为空,建立前驱线索q->lchild = pre;q->ltag = 1;}if (pre != NULL && pre->rchild == NULL) {   pre->rchild = q;    //建立前驱结点的后继线索pre->rtag = 1;}pre = q;           //标记当前结点为刚刚访问过的结点
}

4.3.2 遍历

//3-2.遍历
void PostThread(ThreadTree T) {if (T != NULL) {PostThread(T->lchild);   //后序遍历左子树PostThread(T->rchild);  //后序遍历右子树visit1(T);             //访问根节点}
}

4.3.3 后序线索化主过程

//3-3.主过程
void CreatePostThread(ThreadTree T) {pre = NULL;           //pre初始化为NULLif (T != NULL) {  //非空二叉树才能线索化            PostThread(T);  //后序线索化二叉树if (pre->rchild == NULL) pre->rtag = 1;          //处理遍历的最后一个结点}
}

4.4 寻找后序前驱

//4.寻找后序前驱
ThreadNode* PreNode(ThreadNode* p) {if (p->ltag == 0) {        //若ltag=0,说明所找结点有左孩子if (p->rtag == 0)      //若rtag=0return p->rchild;      //说明所找结点有右孩子,根据后序遍历的特点(左-右-根),右孩子为前驱else                    //若rtag=1return  p->lchild;       //说明所找结点无右孩子,则前驱结点为其左孩子}elsereturn p->lchild; //若ltag=1,说明所找结点无左孩子,则返回前驱线索
}

4.5 逆向后序遍历

4.5.1 打印结点

//5-1.打印结点
void visit2(ThreadNode* p) {printf("%c\t", p->data);
}

4.5.2 利用后序前驱实现逆向后序遍历

//5-2.利用后序前驱实现逆向后序遍历:空间复杂度为O(1)
void RevPostOrder(ThreadNode* T) {for (ThreadNode* p = T; p != NULL; p = PreNode(p))visit2(p);
}

4.6 main函数

int main() {ThreadTree T;/*1、创建二叉树*/printf("先序创建二叉树:");CreateThTree(T);/*2、初始化tag为0*/InitThread(T);/*3、后序线索化*/CreatePostThread(T);/*4、寻找后序前驱(用根结点测试)*/printf("根结点的后序前驱为:%c\n", PreNode(T)->data);/*6、逆向后序遍历二叉树*/printf("<————逆向后序遍历————>\n");RevPostOrder(T);return 0;
}

4.7 测试

4.7.1 二叉树结构

4.7.2 测试结果

5.小结

  • 对于后序线索二叉树并不会出现“转圈"现象,原因是根结点是最后被访问的,不可能再回去访问其左右孩子指向的子树。
  • 另外,同先序线索二叉树一样,后序线索二叉树也存在类似的问题:即只能找到后序前驱。具体分析同先序线索二叉树类似,已在上一篇文章小结中介绍,此处不再展开。

【数据结构】-线索二叉树(后序)相关推荐

  1. c++ stack 遍历_五分钟C语言数据结构 之 二叉树后序遍历(非递归很重要)

    五分钟C语言实现常见数据结构 今天的内容分享的是二叉树后序遍历 DP问题,欢迎关注 动态规划一篇就够了 全网最详细, 逐步理解, 万字总结 - Johngo的文章 - 知乎 https://zhuan ...

  2. (数据结构)二叉树后序遍历

    二叉树后序遍历 二叉树后序遍历的实现思想是: 访问当前节点的左子树 访问当前节点的右子树 访问根节点 图 1 二叉树 以上图 1 为例,后序遍历的过程如下: 从根节点 1 开始,遍历该节点的左子树(以 ...

  3. 线索二叉树 C语言 数据结构 先序线索二叉树 中序线索二叉树 后序线索二叉树

    在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序.中序.后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化. 文章目录 一.c语言实现先序线索.中序线 ...

  4. 线索二叉树(中序、先序和后序及遍历)

    链式存储 线索二叉树是二叉树的一类,在看线索二叉树之前我们先看一下二叉树的链式存储. 一个二叉树的存储例子(后面用到的二叉树都是这棵): 代码是这样的: public class BinaryTree ...

  5. sdut 2137 数据结构实验之求二叉树后序遍历和层次遍历

    数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Descr ...

  6. 数据结构实验之求二叉树后序遍历和层次遍历

    数据结构实验之求二叉树后序遍历和层次遍历 Description 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历和层序遍历. Input 输入数据有多组,第一行是一个整数t (t<100 ...

  7. 数据结构之 二叉树---求二叉树后序遍历和层次遍历(先建树,再遍历)

    数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入 ...

  8. 线索二叉树中序非递归线索化以及递归线索化构建和遍历算法

    引文 大部分教材给出了 线索二叉树的中序递归线索化以及中序遍历,但是没给出非递归,现在网上大部分非递归算法代码各种条件判断写的比较离谱,所以干脆自己总结了一个清晰的.线索二叉树中序非递归线索化以及递归 ...

  9. 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...

    二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...

最新文章

  1. 生成keystore是报错拒绝访问(已测试)
  2. 鸿蒙系统8月7号,主动告别安卓,华为或很快推出搭载鸿蒙系统的手机
  3. 更改UISwitch大小
  4. linux之find
  5. ㉔云上场景:瑞云科技,支持Render cloud的超强计算
  6. 将Web项目部署到华为云服务器的Linux的Tomcat中
  7. 豆果美食,把人们带回厨房
  8. java如何实现定时任务_Java定时任务的三种实现方式
  9. mysql用创建的用户登陆并修改表格_MySQL 基础学习二:创建一个用户表,并增删改查...
  10. python从小到大的顺序输出_「小白专栏」Python中使用for循环,为什么输出结果不是按顺序?...
  11. oracle logfile sync,oracle等待事件3构造一个DirectPathwrite等待事件和构造一个LogFileSync等待事件...
  12. Android10一直获取IP地址,Android 获取IP地址的实现方法
  13. No module named sqlite3解决
  14. 他曾经复读才考上三本,如今让华为开出 201 万年薪(其实还拒绝了 360 万 offer)...
  15. tongweb自动部署_用apache配置TongWeb集群
  16. java实现医嘱管理系统_Chis5.0医嘱管理系统业务使用手册
  17. deepin系统文本编辑器
  18. 顶顶通软电话介绍-一个网络电话客户端(SIP软电话)
  19. 鱼塘钓鱼(贪心算法)--算法设计
  20. Linux下qt程序部署到ARM开发板上: error: Upload of file “你的程序“ failed. The server said: “Failure

热门文章

  1. CodeMix使用教程:构建管道和验证
  2. 【深度学习】 NLP和神经网络表示
  3. 树莓派VNC分辨率,修改无效的解决方案
  4. Python可迭代对象和迭代器对象详解
  5. 获取基站LAC CID
  6. python apriori算法 sklearn_sklearn(九)apriori 关联规则算法,以及FP-growth 算法
  7. 2023年4月实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】
  8. android+网络下载资源,【已解决】Android中利用HttpClient等库实现网络文件下载
  9. Linux下的cut选取命令详解
  10. HikariPool-1 -Starting...