1)
n
个结点的二叉链表中含有
n+1 【
公式
2n-
(n-1)=
n+1】
个
空指针域。利用二叉链表中的空指针域,存放指
向
该
结
点
在
某种遍历次序
下的前驱和后继结
点的指针(
这种附加的指针称为
"
线索
"
)
2)
这
种加上了线索的二叉链表称为
线索链表
,相应的二叉树称为
线索二叉树
(Threaded
BinaryTree
)
。根据线索性质的不同,线索二叉树可分为
前序线索二叉树、中序线索二叉树
和
后序线索二叉树
三
种
3)
一个结点的前一
个结点
,称为
前驱
结点
4)
一个结点
的后一
个结点
,称为
后继
结点
![](https://i-blog.csdnimg.cn/blog_migrate/badf58c48c61371fc5c6c8bbc744564a.png)
中序遍历的结果:{8, 3, 10, 1, 14, 6}
当线索化二叉树后,Node节点的 属性 left 和 right
1)left 指向的是左子树,也可能是指向的前驱节点. 比如 ① 节点 left 指向的左子树, 而 ⑩ 节点的 left 指向的就是前驱节点.
2)right指向的是右子树,也可能是指向后继节点,比如 ① 节点right 指向的是右子树,而⑩ 节点的right 指向的是后继节点.
package com.zhen;
public class ClueBinary {
public static void main(String[] args) {
//手动创建
Node root = new Node(1, "1");
Node node2 = new Node(3, "3");
Node node3 = new Node(6, "6");
Node node4 = new Node(8, "8");
Node node5 = new Node(10, "10");
Node node6 = new Node(14, "14");
root.setLeft(node2);
root.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
node3.setLeft(node6);
//测试
ClueTree clueTree = new ClueTree();
clueTree.infixNode(root);
Node left5 = node5.getLeft();
Node right5 = node5.getRight();
System.out.println("10的前驱节点为:"+left5);
System.out.println("10的后继节点为:"+right5);
System.out.println("线索化遍历:");
clueTree.setRoot(root);
clueTree.infixList();
}
}
//线索二叉树
class ClueTree{
//根节点
private Node root;
//用于保留线索化的前一个节点
private Node pre=null;
public void setRoot(Node root) {
this.root = root;
}
//中序线索化
public void infixNode(Node node) {
if (node==null) {
return;
}
//1.线索化左子树
infixNode(node.getLeft());
//2.线索化当前节点
//处理当前节点的前驱节点
if (node.getLeft()==null) {
//指向前驱节点
node.setLeft(pre);
node.setLeftType(1);
}
//处理后继节点
if (pre!=null&&pre.getRight() == null) {
pre.setRight(node);
pre.setRightType(1);
}
//每处理一个节点后,让当前节点是下一个节点的前驱节点
pre=node;
//3.线索化右子树
infixNode(node.getRight());
}
//遍历中序线索二叉树
public void infixList() {
//存储当前遍历的节点从root开始
Node node=root;
while (node != null) {
//循环去找leftType=1的节点,因为该节点为有效节点
//跳过为0的
while(node.getLeftType()==0) {
node=node.getLeft();
}
//打印当前节点
System.out.println(node);
while(node.getRightType()==1) {
//获取后继节点
node = node.getRight();
System.out.println(node);
}
//不等于1就替换
node=node.getRight();
}
}
}
//节点
class Node{
private int no;
private String name;
private Node left;
private Node right;
//如果leftType=0指向左子树,leftType=1指向前驱节点
private int leftType;
//如果rightType=0指向右子树,rightType=1指向后继节点
private int rightType;
public Node(int no, String name) {
super();
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public int getLeftType() {
return leftType;
}
public void setLeftType(int leftType) {
this.leftType = leftType;
}
public int getRightType() {
return rightType;
}
public void setRightType(int rightType) {
this.rightType = rightType;
}
@Override
public String toString() {
return "Node [no=" + no + ", name=" + name + "]";
}
}