线索二叉树
1. 基本介绍
n
个结点的二叉链表中含有 n+1
【公式 2n-(n-1)=n+1
】 个空指针域。利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")。- 这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树(
Threaded BinaryTree
)。根据线索性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树和后序线索二叉树三种。 - 一个结点的前一个结点,称为前驱结点。
- 一个结点的后一个结点,称为后继结点。
2. 代码实现(前序、中序、后序线索化二叉树及遍历)
public class ThreadTreeDemo {
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
Node node6 = new Node(6);
Node node7 = new Node(7);
Node node8 = new Node(8);
node1.setLChildNode(node2);
node1.setRChildNode(node3);
node2.setLChildNode(node4);
node3.setLChildNode(node5);
node3.setRChildNode(node6);
node5.setLChildNode(node7);
node5.setRChildNode(node8);
ThreadTree threadTree = new ThreadTree(node1);
}
}
class ThreadTree {
private Node root;
private Node pre;
public ThreadTree(Node root) {
this.root = root;
}
public void preThreadTree() {
preThreadTree(root);
}
public void infixThreadTree() {
infixThreadTree(root);
}
public void postThreadTree() {
postThreadTree(root);
}
private void preThreadTree(Node node) {
if (node == null) {
return;
}
if (node.getLChildNode() == null) {
node.setLChildNode(pre);
node.setLTag(1);
}
if (pre != null && pre.getRChildNode() == null) {
pre.setRChildNode(node);
pre.setRTag(1);
}
pre = node;
if (node.getLTag() == 0) {
preThreadTree(node.getLChildNode());
}
if (node.getRTag() == 0) {
preThreadTree(node.getRChildNode());
}
}
private void infixThreadTree(Node node) {
if (node == null) {
return;
}
if (node.getLTag() == 0) {
infixThreadTree(node.getLChildNode());
}
if (node.getLChildNode() == null) {
node.setLChildNode(pre);
node.setLTag(1);
}
if (pre != null && pre.getRChildNode() == null) {
pre.setRChildNode(node);
pre.setRTag(1);
}
pre = node;
if (node.getRTag() == 0) {
infixThreadTree(node.getRChildNode());
}
}
private void postThreadTree(Node node) {
if (node == null) {
return;
}
if (node.getLTag() == 0) {
postThreadTree(node.getLChildNode());
}
if (node.getRTag() == 0) {
postThreadTree(node.getRChildNode());
}
if (node.getLChildNode() == null) {
node.setLChildNode(pre);
node.setLTag(1);
}
if (pre != null && pre.getRChildNode() == null) {
pre.setRChildNode(node);
pre.setRTag(1);
}
pre = node;
}
public void preThreadTreeList() {
if (root != null) {
Node temp = root;
while (temp != null) {
while (temp.getLTag() == 0) {
System.out.println(temp);
temp = temp.getLChildNode();
}
System.out.println(temp);
temp = temp.getRChildNode();
}
}
}
public void infixThreadTreeList() {
if (root != null) {
Node temp = root;
while (temp != null) {
while (temp.getLTag() == 0) {
temp = temp.getLChildNode();
}
System.out.println(temp);
while (temp.getRTag() == 1) {
temp = temp.getRChildNode();
System.out.println(temp);
}
temp = temp.getRChildNode();
}
}
}
}
class Node {
private int data;
private Node LChildNode;
private Node RChildNode;
private int LTag;
private int RTag;
public Node(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLChildNode() {
return LChildNode;
}
public void setLChildNode(Node LChildNode) {
this.LChildNode = LChildNode;
}
public Node getRChildNode() {
return RChildNode;
}
public void setRChildNode(Node RChildNode) {
this.RChildNode = RChildNode;
}
public int getLTag() {
return LTag;
}
public void setLTag(int LTag) {
this.LTag = LTag;
}
public int getRTag() {
return RTag;
}
public void setRTag(int RTag) {
this.RTag = RTag;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
'}';
}
}