议题:线索二叉树(Threaded Binary Tree)

分析:

  • 为除第一个节点外的每个节点添加一个指向其前驱节点的指针,为除最后一个节点外的每个节点添加一个指向其后续节点的指针,通过这些额外的指针可以某种遍历方式对二叉树进行遍历,而加了这些额外指针的二叉树就是线索二叉树;

  • 对于含有N个节点的二叉树而言,一共有2N个指针,但除了根节点的其他节点都有来自其父节点的指针,所以耗用了N-1个指针,则最终剩下2N-(N- 1)=N+1个空指针;线索二叉树就是利用这些空指针存储具有某种遍历顺序的前驱和后续,就遍历顺序而言线索二叉树分为:前序,中序和后序三种线索二叉 树;

  • 将一棵二叉树进行线索化就是为其空指针赋值的过程,所以需要对二叉树进行对应的遍历(如构建前序线索二叉树,就需要对二叉树进行前序遍历);如下例子是将一棵二叉树线索化为一棵中序线索二叉树,

  • 构建线索二叉树的时间复杂度为O(N),其可以在O(1)或者O(logN)的时间复杂度内找到指定节点在某种遍历下的前驱和后续,但是其维护成本较高,但插入或者删除节点的时候,需要花费额外的时间维护线索指针的正确性;

样例:

 struct ThreadedNode {
int value;
int Lthread;
int Rthread;
ThreadedNode *left;
ThreadedNode *right;
};
/**
* 这里仅实现了中序线索化,前序跟后序线索化的实现只是处理节点的顺序
* 更改
* */
void InOrderThreaded(ThreadedNode *cur, ThreadedNode *pre) {
if(cur==NULL)
return;
else {
/**
* 中序遍历:首先处理左子树,然后当前节点,最后右子树
* */
InOrderThreaded(cur->left, pre); /**
* 首先对当前节点的Lthread和Rthread标志进行初始化
* */
if(cur->left==NULL)
cur->Lthread=;
else
cur->Lthread=; if(cur->right==NULL)
cur->Rthread=;
else
cur->Rthread=;
/**
* 一开始pre需要设置为NULL,但是也可以创建一个head节点,这样就
* 不用每次都进行pre!=NULL的判断
* */
if(pre!=NULL) {
/**
* 完成前一个节点的后续线索化
* */
if(pre->Rthread==)
pre->right=cur;
/**
* 完成当前节点的前驱线索化
* */
if(cur->Lthread==)
cur->left=pre;
}
pre=cur; InOrderThreaded(cur->right, pre);
}
} /**
* 查找给定节点target在线索二叉树root的中序遍历中的后续节点successor
* 分两种情况:
* 1. 如果target的右子树非空,则其后续节点是中序遍历右子树的第一个节点,O(logN)
* 2. 如果target的右子树为空,则其后续节点直接就是target->right指向的节点,利用线索化优势,O(1)
* */
ThreadedNode* FindSuccessor(ThreadedNode *target) {
/**
* 利用线索化标记进行判断
* */
if(target->Rthread==)
return target->right;
else {
ThreadedNode *temp=target->right;
/**
* 利用线索化标记进行判断
* */
while(temp->Lthread==)
temp=temp->left;
return temp;
}
} /**
* 查找给定节点target在线索二叉树root的中序遍历中的前驱节点precursor
* 分两种情况:
* 1. 如果target的左子树非空,则其前驱节点是中序遍历左子树的最后一个节点,O(logN)
* 2. 如果target的左子树为空,则其前驱节点就直接是target->left指向的节点,利用线索化优势,O(1)
* */
ThreadedNode* FindPrecursor(ThreadedNode *target) {
if(target->Lthread==)
return target->left;
else {
ThreadedNode *temp=target->left;
while(temp->Rthread==)
temp=temp->right;
return temp;
}
}

参考连接:
http://student.zjzk.cn/course_ware/data_structure/web/main.htm

笔试算法题(41):线索二叉树(Threaded Binary Tree)的更多相关文章

  1. 遍历二叉树 traversing binary tree 线索二叉树 threaded binary tree 线索链表 线索化

    遍历二叉树   traversing binary tree 线索二叉树 threaded binary tree 线索链表 线索化 1. 二叉树3个基本单元组成:根节点.左子树.右子树 以L.D.R ...

  2. 线索二叉树Threaded binary tree

    摘要   按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列.在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点:除最后一个结点外每一个结点有且仅有一个直接后继结点.这 ...

  3. LeetCode算法题-Average of Levels in Binary Tree(Java实现)

    这是悦乐书的第277次更新,第293篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第145题(顺位题号是637).给定一个非空二叉树,以数组的形式返回每一层节点值之和的平 ...

  4. 力扣算法题—111.Minimum Depth of Binary Tree

      Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the sh ...

  5. 数据结构《9》----Threaded Binary Tree 线索二叉树

    对于任意一棵节点数为 n 的二叉树,NULL 指针的数目为  n+1 , 线索树就是利用这些 "浪费" 了的指针的数据结构. Definition: "A binary ...

  6. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  7. php算法题---对称的二叉树

    php算法题---对称的二叉树 一.总结 一句话总结: 可以在isSymmetrical()的基础上再加一个函数comRoot,函数comRoot来做树的递归判断 /*思路:首先根节点以及其左右子树, ...

  8. 对称二叉树 · symmetric binary tree

    [抄题]: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). ...

  9. 数据结构-二叉树(Binary Tree)

    1.二叉树(Binary Tree) 是n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根节点和两棵互不相交的,分别称为根节点的左子树和右子树的二叉树组成.  2.特数二 ...

随机推荐

  1. python运行selenium时出现的一个错误总结

    1.SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame 场景:运用pan ...

  2. 【SpringCloud构建微服务系列】微服务网关Zuul

    一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...

  3. ElasticSearch | windows 上安装ES

    Elastatic需要java JAVA8 环境,确保安装好环境 在windows上安装ES还是比较简单的, 1.首先在官网上下载zip,地址 https://www.elastic.co/downl ...

  4. Selenium定位多个iframe嵌套中的元素

    在公司boss系统中,经常会遇到多层iframe嵌套的情况,导致无法定位最里面那层iframe的元素. 其实很简单,只要一层层定位iframe,定位到你想要的那层iframe即可: 如果操作完需要返回 ...

  5. django views视图函数

    Django views.py视图文件 一. 创建views.py文件,在工程文件夹根目录创建views.py视图文件,其实任意文件名都可以,使用views是为了遵循传统. 注:所有的views函数都 ...

  6. 贪心 UVALive 6832 Bit String Reordering

    题目传送门 /* 贪心:按照0或1开头,若不符合,选择后面最近的进行交换.然后选取最少的交换次数 */ #include <cstdio> #include <algorithm&g ...

  7. composer 加快更新速度

    一.使用代理 set http_proxy=http://127.0.0.1:8087 //Windows export http_proxy=http://127.0.0.1:8087 //linu ...

  8. VS2010环境下.NET4.0中Tuple<T>的一个小BUG问题

    启动一个桌面程序后,发现一个窗体cfdata=null, 执行时发生错误, 但是在初始化的时候,我明明是cfdata=new Cfdata();为什么会出现这个错误呢. 我开始跟踪,发现当执行cfda ...

  9. UIAlertController的使用,代替UIAlertView和UIActionSheet

    在iOS8以后,UIAlertView就开始被抛弃了. 取而代之是UIAlertController 以前是警示框这样写: UIAlertView *alert = [[UIAlertView all ...

  10. 应用CSS样式表

    首先应该分清楚应用CSS样式表到HTML页面中和将css样式表绑定到HTML页面的对象,是两个不同的概念.像之前说的通过不同的选择器将样式表绑定到HTML页面中的对象,但其实使用的都是同一种方法应用c ...