線索二叉樹的生成及遍歷
阿新 • • 發佈:2019-02-05
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; } } }