先序、中序线索化二叉树![](https://i-blog.csdnimg.cn/blog_migrate/9d37711240aa1cf604420ad69e5c740b.png)
后序线索化二叉树:三叉链表
getFirst的思路
getNext的思路
先序、中序、后序线索化二叉树,并遍历
public class ThreadedBinaryTree {
private Node root;
private Node pre;//指向当前节点的前驱节点
private Node parent;//指向当前节点的双亲节点
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
public static int num = 0;
public Node createTree(int[] arr) {
if (num >= arr.length) {
return null;
}
Node root = null;
if (arr[num] != 0) {
root = new Node(arr[num]);//创建当前节点
if (num == 0) {
this.root = root;//设置根节点
}
num++;
}
if (arr[num] != 0) {
root.left = createTree(arr);
root.left.parent = root;//方便后序遍历
} else {
root.left = null;
num++;
}
if (arr[num] != 0) {
root.right = createTree(arr);
root.right.parent = root;//方便后序遍历
} else {
root.right = null;
num++;
}
return root;
}
/**
* 中序线索二叉树
*/
//重载中序线索二叉树
public void threadedInfixNodes() {
threadedInfixNodes(root);
}
//中序线索二叉树
public void threadedInfixNodes(Node node) {
if (node == null) {
return;
}
//node左子节点线索化
threadedInfixNodes(node.left);
//node节点线索化
if (node.left == null) {
node.left = pre;
node.leftType = 1;
}
if (pre != null && pre.right == null) {
pre.right = node;
pre.rightType = 1;
}
pre = node;
//node右子节点线索化
threadedInfixNodes(node.right);
}
//遍历中序线索二叉树
public void infixPrint() {
Node node = root;
while (node != null) {
while (node.leftType == 0) {
node = node.left;
}
System.out.print(node.no + " ");
while (node.rightType == 1) {
System.out.print(node.right.no + " ");
node = node.right;
}
node = node.right;
}
}
//遍历中序线索二叉树
public void infixPrint2() {
Node node = root;
while (node.leftType == 0) {
node = node.left;
}
System.out.print(node.no + " ");//找到了第一个
while (node.rightType == 1) {
System.out.print(node.right.no + " ");
node = node.right;
}
node = node.right;
}
/**
* 先序线索二叉树
*/
//重载先序线索二叉树
public void threadedPreNodes() {
threadedPreNodes(root);
}
//先序线索二叉树
public void threadedPreNodes(Node node) {
if (node == null) {
return;
}
//node节点线索化
if (node.left == null) {
node.left = pre;
node.leftType = 1;
}
if (pre != null && pre.right == null) {
pre.right = node;
pre.rightType = 1;
}
pre = node;
//node左右边子节点线索化
//!!!需要判断leftType和rightType是否等于0,
//存在一种可能:node.left本来是为null的,但在线索化node的时候,将node.left指向了pre
//所以如果不进行判断就会再次调用pre,进入死循环
if (node.leftType == 0) {
threadedPreNodes(node.left);
}
//node右子节点线索化
if (node.rightType == 0) {
threadedPreNodes(node.right);
}
}
//遍历先序线索二叉树
public void prePrint() {
Node node = root;
while (node != null) {
System.out.print(node.no + " ");
while (node.leftType == 0) {
node = node.left;
System.out.print(node.no + " ");
}
while (node.rightType == 1) {
node = node.right;
System.out.print(node.no + " ");
}
node = node.right;
}
}
/**
* 后序线索二叉树
*/
//重载后序线索二叉树
public void threadedPostNodes() {
threadedPostNodes(root);
}
//后序线索二叉树
public void threadedPostNodes(Node node) {
if (node == null) {
return;
}
//node左子节点线索化
threadedPostNodes(node.left);
//node右子节点线索化
threadedPostNodes(node.right);
//node节点线索化
if (node.left == null) {
node.left = pre;
node.leftType = 1;
}
if (pre != null && pre.right == null) {
pre.right = node;
pre.rightType = 1;
}
pre = node;
}
//遍历后序线索二叉树
public void postPrint() {
Node first = getFirst(root);
while (first != null) {
System.out.print(first.no + " ");
first = getNext(first);
}
}
public Node getFirst(Node node) {
while (node.leftType == 0) {
//如果有左孩子就一直往左找
node = node.left;
}
//判断有没有右孩子
if (node.rightType == 0) {
return getFirst(node.right);
}
return node;
}
public Node getNext(Node node) {
if (node.rightType == 1) {
return node.right;
} else {
if (node.parent == null) {
//该节点是根节点
return null;
} else if (node.parent.left.no == node.no) {
//该节点是其双亲节点的左节点
if (node.parent.rightType == 0) {
//该节点的双亲结点有右子节点
//接着找以双亲结点的右子节点为跟节点的子树的第一个节点
return getFirst(node.parent.right);
} else {
//该节点的双亲节点没有右子节点
return node.parent;
}
} else if (node.parent.right.no == node.no) {
//该节点是其双亲节点的右节点
return node.parent;
}
}
return null;
}
}
public class Node {
public int no;
public Node left;
public Node right;
public Node parent;
//leftType:0表示左子树,1表示前驱节点
public int leftType;
//rightType:0表示右子树,1表示后继节点
public int rightType;
public Node() {
}
public Node(int no) {
this.no = no;
}
public void preOrder() {
System.out.print(this.no + " ");
if (this.left != null) {
this.left.preOrder();
}
if (this.right != null) {
this.right.preOrder();
}
}
public void infixOrder() {
if (this.left != null) {
this.left.infixOrder();
}
System.out.print(this.no + " ");
if (this.right != null) {
this.right.infixOrder();
}
}
public void postOrder() {
if (this.left != null) {
this.left.postOrder();
}
if (this.right != null) {
this.right.postOrder();
}
System.out.print(this.no + " ");
}
}
public class ThreadedBinaryTreeDemo {
public static void main(String[] args) {
// ThreadedBinaryTree tbt = new ThreadedBinaryTree();
// Node node1 = new Node(1);
// Node node3 = new Node(3);
// Node node6 = new Node(6);
// Node node8 = new Node(8);
// Node node10 = new Node(10);
// Node node12 = new Node(12);
// Node node14 = new Node(14);
// Node node16 = new Node(16);
// tbt.setRoot(node1);
// node1.left = node3;
// node1.right = node6;
// node3.left = node8;
// node3.right = node10;
// node8.right = node12;
// node6.left = node14;
// node14.right = node16;
// tbt.getRoot().preOrder();//1 3 8 12 10 6 14 16
// System.out.println();
// tbt.getRoot().infixOrder();//8 12 3 10 1 14 16 6
// System.out.println();
// tbt.getRoot().postOrder();//12 8 10 3 16 14 6 1
// System.out.println();
//根据先序遍历结果创建二叉树
ThreadedBinaryTree tbt = new ThreadedBinaryTree();
int[] arr = {1, 3, 8, 0, 12, 0, 0, 10, 0, 0, 6, 14, 0, 16, 0, 0, 0};
Node root = tbt.createTree(arr);
root.preOrder();//1 3 8 12 10 6 14 16
System.out.println();
root.infixOrder();//8 12 3 10 1 14 16 6
System.out.println();
root.postOrder();//12 8 10 3 16 14 6 1
System.out.println();
System.out.println("--------------------");
//中序线索化二叉树,并遍历
tbt.threadedInfixNodes();
tbt.infixPrint();
// //先序线索化二叉树,并遍历
// tbt.threadedPreNodes();
// tbt.prePrint();
//
// //后序线索化二叉树,并遍历
// tbt.threadedPostNodes();
// tbt.postPrint();
}
}