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

Definition:

"A binary tree is threaded by making
all right child pointers that would normally be null point to the inorder successor of the node, and all left child pointers that would normally be null point to the inorder predecessor of the node."

将一棵普通的二叉树中任一节点的     空右孩子指针 指向 中序遍历的后继节点, 空左孩子指针 指向 中序遍历的前继节点。

实际上就是利用那些空指针,使其指向节点中序遍历的后继节点,前继节点。

特点:

1. 能够用常数空间复杂度,来进行二叉树的遍历。

2. 在不显式使用 parent pointer 或 栈 的情况, 也能够找到节点的父亲节点, 虽然比较慢。

假设某一节点 k, 有一个右孩子 r。 那么 r 的 left pointer 要么是一个thread 指向 k, 要么就是一个孩子。如果 r 有一个左孩子,那么这个左孩子的 left pointer 要么是一个thread指向 k, 要么也是一个孩子,如此类推。。所以在r 的“最左”的孩子一定指向 k。

对于k 的 左孩子的情况是类似的,也能够找到父亲节点。

线索二叉树的数据结构:

typedef enum {THREAD, LINK } PointerFlag;
//标记指针是 线索 还是 正常的Link

struct ThTreeNode{
char val;
ThTreeNode *left;
ThTreeNode *right;
PointerFlag l_tag;
PointerFlag r_tag;
ThTreeNode()
:left(NULL), right(NULL), l_tag(LINK), r_tag(LINK){}
};

二叉树的线索化:

利用中序遍历,将叶子节点空指针线索化。

void InThreading(ThTreeNode *root)
{
if(root == NULL) return; InThreading(root->left); //线索化左子树 if(g_pre->right == NULL){ //全局变量g_pre指向中序遍历访问的前一个节点
g_pre->r_tag = THREAD;
g_pre->right = root;
}
if(root->left == NULL){
root->l_tag = THREAD;
root->left = g_pre;
}
g_pre = root; InThreading(root->right); //线索化右子树
}

线索二叉树的遍历:

时间复杂度O(n), 空间复杂度O(1).

void InOrderTraversal(ThTreeNode *head)
{
ThTreeNode *p = head->left; // head指向头节点,头节点的左孩子是 根节点 while(p != head){
while(p->l_tag == LINK) p = p->left;
cout << p->val << " "; while(p->r_tag == THREAD && p->right != head){
p = p->right;
cout << p->val << " ";
} p = p->right;
}
}

完整的代码:

/**
* copyright @ L.J.SHOU Feb.10, 2014
* threaded binary tree
*/
#include "threaded-binary-tree.h"
#include <iostream>
#include <cstring>
#include <cassert>
using std::cout;
using std::cin;
using std::string;
using std::endl; // global variant: previous visited node
ThTreeNode *g_pre(NULL); void InThreading(ThTreeNode *root)
{
if(root == NULL) return; InThreading(root->left); if(g_pre->right == NULL){
g_pre->r_tag = THREAD;
g_pre->right = root;
}
if(root->left == NULL){
root->l_tag = THREAD;
root->left = g_pre;
}
g_pre = root; InThreading(root->right);
} ThTreeNode* InOrderThreading(ThTreeNode *root)
{
ThTreeNode *head(NULL); //头节点
head = new ThTreeNode();
head->l_tag = LINK;
head->r_tag = THREAD;
if(root == NULL) head->left = head;
else{
head->left = root; g_pre = head;
InThreading(root);
g_pre->right = head; g_pre->r_tag = THREAD;
head->right = g_pre; //head->right指向中序遍历最后一个节点
} return head;
} void InOrderTraversal(ThTreeNode *root)
{
ThTreeNode *p = root->left; // p 指向根节点 while(p != root){
while(p->l_tag == LINK) p = p->left;
cout << p->val << " "; while(p->r_tag == THREAD && p->right != root){
p = p->right;
cout << p->val << " ";
} p = p->right;
}
} ThTreeNode* Destroy(ThTreeNode *root)
{
if(root){
if(root->l_tag == LINK)
root->left = Destroy(root->left);
if(root->r_tag == LINK)
root->right = Destroy(root->right);
delete root;
}
return NULL;
}

数据结构《9》----Threaded Binary Tree 线索二叉树的更多相关文章

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

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

  2. 笔试算法题(41):线索二叉树(Threaded Binary Tree)

    议题:线索二叉树(Threaded Binary Tree) 分析: 为除第一个节点外的每个节点添加一个指向其前驱节点的指针,为除最后一个节点外的每个节点添加一个指向其后续节点的指针,通过这些额外的指 ...

  3. [LintCode] Invert Binary Tree 翻转二叉树

    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...

  4. 【LeetCode-面试算法经典-Java实现】【104-Maximum Depth of Binary Tree(二叉树的最大深度)】

    [104-Maximum Depth of Binary Tree(二叉树的最大深度)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a binary t ...

  5. 线索二叉树Threaded binary tree

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

  6. ※数据结构※→☆非线性结构(tree)☆============二叉树 顺序存储结构(tree binary sequence)(十九)

    二叉树 在计算机科学中,二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用作二叉查找树和二叉堆或是 ...

  7. 226. Invert Binary Tree 翻转二叉树

    [抄题]: Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 [暴力解法]: 时间分析: 空间分 ...

  8. [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  9. [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化

    One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...

随机推荐

  1. 1029c语言文法

    <程序>→<外部声明>|<程序><外部声明> <外部声明>→<函数定义>|<声明> <函数定义>→< ...

  2. jquery 常用函数集锦

    html() 方法的功能是设置或获取元素中显示的内容css() 方法的功能是设置或获取元素的某项样式属性 $("#61dh a").css('color','#123456'); ...

  3. 20150206读书笔记<深入理解计算机系统>

    ●第一章 C是系统级编程的首选.C++显示支持抽象,属于应用级程序设计语言. 简单例子: 一个典型系统的硬件组成: 存储器的层次结构: 注:存储器层次结构的设计思想是,该层存储器作为下一层存储器的高速 ...

  4. Tengine vs openresty

      简介 Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到 ...

  5. PHP获取当前页面的URL作为参数以供下一层的页面可以返回上一层页面

    1.基础url的获取 #测试网址: http://localhost/blog/testurl.php?id=5 //获取域名或主机地址 echo $_SERVER['HTTP_HOST'].&quo ...

  6. 获取图片颜色的rgb,以供css设计背景颜色

    ColorPix

  7. BZOJ4007 [JLOI2015]战争调度

    根本想不出来... 原来还是暴力出奇迹啊QAQ 无限ymymym中 /************************************************************** Pr ...

  8. mybatis使用

    mybatis网站:http://mybatis.github.io/spring/zh/ mybatis spring下载网址:https://github.com/mybatis/spring/r ...

  9. 53个要点提高PHP编程效率

    1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.$row[’id’] 的速度是$row[id]的7倍.3.echo 比 print 快,并且使用echo ...

  10. jq 判断输入数字

    jq 判断输入数字 <input   id="N_source" name="N_source"   type="text" valu ...