二叉树线索化

网上二叉树线索化的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;	
		}


}

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值