网上二叉树线索化的JAVA实现代码相对较少,今天在中序遍历的基础上较小的改变实现了二叉树中序线索化的递归和非递归算法,思路非常简洁,对比非常明显,相信大家一看就懂。
背景:对于一个n个节点的二叉树,除了根节点外每个节点都有一个指向父亲的引用,因此有n-1个引用,而n个节点总共有2*n个引用,因此还有n+1个引用没有使用,如果把这些引用分别指向当前节点的前驱或者后继,则将此二叉树线索化。线索化后的二叉树遍历比较方便,不需要递归,效率快。
本文以中序为例,下面是中序线索化的Java代码。(其他序列的线索化可以参考我的前一篇文章的二叉树遍历进行修改)
package Tree;
import java.util.Stack;
public class ThreadedBinTree {
public static void main(String[] args) {
binTree tree = new binTree();
tree.insertNode(4);
tree.insertNode(3);
tree.insertNode(2);
tree.insertNode(1);
tree.insertNode(3);
tree.insertNode(5);
tree.insertNode(7);
tree.insertNode(6);
System.out.println("midOrder");
tree.midOrderTraverse(tree.getRoot());
System.out.println();
System.out.println("midOderNocursor");
tree.midOrderTraverseNoRecursion(tree.getRoot());
System.out.println();
//---------------------------------------------------------------------------
System.out.println("线索二叉树,非递归");
Node<Integer> headNode = tree.BinTreeThreaded(tree.getRoot());
while(headNode != null){
System.out.print(headNode.value+" ");
headNode = headNode.right;
}
System.out.println();
//************************两个选择一个运行***************运行一次改变了Tree的结构************
/*System.out.println("线索二叉树,递归");
Node<Integer> headNode = tree.BinTreeThreadedRecursion(tree.getRoot());
while(headNode != null){
System.out.print(headNode.value+" ");
headNode = headNode.right;
}
System.out.println();*/
//---------------------------------------------------------------------------
System.out.println("end---");
}
}
class Node<E extends Comparable<E>>{
E value;
Node<E> left;
Node<E> right;
Node(){
}
Node(E value){
this.value = value;
}
}
//二叉排序树
class binTree<E extends Comparable<E>>{
private Node <E> root ;
public binTree() {
// TODO Auto-generated constructor stub
root = null;
}
public Node<E> getRoot(){
return this.root;
}
//插入节点
public void insertNode(E value){
if(root == null){
root = new Node<E>(value);
return;
}
Node<E> currentNode = root;
while(true){
if(value.compareTo(currentNode.value) < 0){
if(currentNode.left == null){
currentNode.left = new Node<E>(value);
return;
}
currentNode = currentNode.left;
}
else{
if(currentNode.right == null){
currentNode.right = new Node<E>(value);
return;
}
currentNode = currentNode.right;
}
}
}
//中序遍历 递归
public void midOrderTraverse(Node<E> root){
if(root.left != null)
midOrderTraverse(root.left);
System.out.print(root.value+" ");
if(root.right != null)
midOrderTraverse(root.right);
}
//中序遍历 非递归
public void midOrderTraverseNoRecursion(Node<E> root) {
Stack<Node<E>> stack = new Stack<Node<E>>();
Node<E> currentNode = root;
while(currentNode!=null || !stack.isEmpty()){
if (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}else{
currentNode = stack.pop();
System.out.print(currentNode.value+" ");
currentNode = currentNode.right;
}
}
}
//中序线索化二叉排序树,非递归
public Node<E> BinTreeThreaded(Node<E> root){
Node<E> head ; //标记线索化的头部,作为返回值
Node<E> pre =new Node();
head = pre;
//参考中序遍历
Stack<Node<E>> stack = new Stack<Node<E>>();
Node<E> currentNode = root;
while(currentNode!=null || !stack.isEmpty()){
if (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}else{
currentNode = stack.pop();
if(pre.right == null)
pre.right = currentNode; //前一个节点的right指向后一个节点
if(currentNode.left == null)
currentNode.left = pre; //后一个节点的left指向前一个节点
pre = currentNode;
currentNode = currentNode.right;
}
}
return head.right;
}
//中序线索化二叉排序树,递归
public Node<E> BinTreeThreadedRecursion(Node<E> root){
Node<E> head ; //标记线索化的头部,作为返回值
Node<E> pre =new Node();
head = pre;
//参考中序遍历,递归
Stack<Node<E>> stack = new Stack<Node<E>>();
Node<E> currentNode = root;
if(root.left != null)
midOrderTraverse(root.left);
if(pre.right == null)
pre.right = root; //前一个节点的right指向后一个节点
if(root.left == null)
root.left = pre; //后一个节点的left指向前一个节点
pre = root;;
if(root.right != null)
midOrderTraverse(root.right);
return head.right;
}
}