1. 程式人生 > >線索二叉樹的生成及遍歷

線索二叉樹的生成及遍歷

package tree;


/*
 * 線索二叉樹
 */
public class ThreadBinaryTree<E> {
	private E[] elements = null;
	private int count = 0;
	private Node pre;//中序遍歷最後一個結點或中序遍歷前一個結點變數
	private Node lastLeft;//中序遍歷第一個結點
	
	/*前序遞迴生成二叉樹*/
	public Node createBinaryTree(){
		Node node = new Node();
		
		if(count >= elements.length || elements[count++] == "#"){
			return null;
		}else{
			node.element = elements[count - 1];
			node.left = createBinaryTree();
			node.right = createBinaryTree();
		}
		
		return node;
	}
	
	//中序遍歷生成線索二叉樹
	public Node inThreading(Node current){
		if(current != null){
			inThreading(current.left);//遞迴左子樹線索化
			if(current.left == null){ //當前結點沒有左孩子
				current.lefeTag = 1;
				current.left = pre;
			}
			
			if(pre.right == null){ //前驅沒有右孩子
				pre.rightTag = 1;
				pre.right = current;
			}
			
			pre = current;//指向前一個結點
			inThreading(current.right);//遞迴右子樹線索化
		}
		return null;
	}
	
	/*帶頭結點的線索二叉樹*/
	public void inHeadThreading(Node head,Node root){
		if(head == null){
			head = new Node();
		}
		
		if(root == null){
			return;
		}else{
			head.left = root;//頭結點的左孩子指向根結點
			head.lefeTag = 0;
			//使二叉樹中序序列中的第一個結點的left和最後一個結點的right指向頭結點
			//找到第一個結點
			findLastLeftNode(root);
			lastLeft.lefeTag = 1;
			lastLeft.left = head;
			
			inThreading(root);//找到最後一個結點
			head.right = pre;//頭結點右孩子為空,則指向最後一個結點
			head.rightTag = 1;
			pre.right = head;//使得最後一個結點的右孩子指向頭結點
			pre.rightTag = 1;
			
		}
	}


	/*線索二叉樹的遍歷*/
	public void inOrderTreverse(Node head){
		Node current = head.left;
		while(current != head){
			while(current.lefeTag == 0){
				current = current.left;
			}
			System.out.println(current.element);
			
			while(current.rightTag == 1 && current.right != head){
				current = current.right;
				System.out.println(current.element);
			}
			
			current = current.right;
		}
	}
	
	/*找到最左邊的結點,即中序遍歷的第一個結點*/
	public void findLastLeftNode(Node root){
		if(root == null){
			return;
		}
		
		Node current = root;
		while(current.left != null){
			current = current.left;
		}
		
		lastLeft = current;
	}
	
	static class Node<E>{
		int lefeTag; /*如果Tag為0則標識指向左右孩子的指標,如果為1則標識指向前驅或後繼的線索*/
		int rightTag;
		Node<E> left;
		Node<E> right;
		E element;
		
		public Node(){
		}
		
		public Node(E element){
			this.element = element;
		}
	}
}