public interface Tree<E> { boolean isEmpty(); E getRoot (); E getParent(int nodeNum); E getLeftSibling(int nodeNum); E getRightSibling(int nodeNum); TreeNode<E> createNode(int headNum,E l,E r); TreeNode<E> createHead(int headNum,E l,E r); void breadFirstOrder();//Breadth first void preOrder();//Preorder traversal void inOrder();//Inorder traversal void postORrder();//Subsequent traversal void clear();//Delete the entire tree }
class TreeNode<E> { private E item; private E leftSibling; private E rightSibling; TreeNode(E item,E leftSibling,E rightSibling){ this.setItem(item); this.setLeftSibling(leftSibling); this.setRightSibling(rightSibling); } public E getItem() { return item; } public void setItem(E item) { this.item = item; } public E getLeftSibling() { return leftSibling; } public void setLeftSibling(E leftSibling) { this.leftSibling = leftSibling; } public E getRightSibling() { return rightSibling; } public void setRightSibling(E rightSibling) { this.rightSibling = rightSibling; } }
public class ArrayTree<E> implements Tree<E> { public Object[] elementData;//Array to store elements public int level;//The highest level is level 0 public TreeNode<E> root;//跟 public final static int DEFAULT_LEVEL = 10; public ArrayTree(int level) { elementData = new Object[(2 << level) - 1]; this.level = level; } public ArrayTree() { this(DEFAULT_LEVEL); } @Override public boolean isEmpty() { return elementData[0] == null; } @Override public E getRoot () { return (E) elementData[0]; } @Override//Get the parent node Know the position of a node through bit operation to get the position of the parent node public E getParent(int nodeNum) { if (nodeNum % 2 == 0) { return checkIndex((nodeNum >> 1) - 1) ? (E) elementData[(nodeNum - 1) - 1] : null; } else { return checkIndex((nodeNum - 1) >> 1) ? (E) elementData[(nodeNum - 1) >> 1] : null; } } @Override public E getLeftSibling(int nodeNum) { return (checkIndex(nodeNum) && checkIndex(nodeNum << 1 + 1)) ? (E) elementData[nodeNum << 2 + 1] : null; } @Override public E getRightSibling(int nodeNum) { return (checkIndex(nodeNum) && checkIndex((nodeNum + 1) << 1)) ? (E) elementData[(nodeNum + 1) << 1] : null; } @Override public TreeNode<E> createNode(int headNum, E l, E r) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public TreeNode<E> createHead(int headNum, E l, E r) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void breadFirstOrder() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void preOrder() { Stack<Integer> dataStack = new Stack<Integer>();//Use the stack to store the node number int currentNum = 0; String str = ""; while (!dataStack.isEmpty() || elementData[currentNum] != null) { if (checkIndex(currentNum) && elementData[currentNum] != null) { str += (elementData[currentNum] + " "); if (checkIndex((currentNum + 1) << 1) && elementData[(currentNum + 1) << 1] != null) { dataStack.push((currentNum + 1) << 1);//The right child index is put into the stack } currentNum = (currentNum << 1) + 1; } else { currentNum = dataStack.pop(); } } System.out.println(str); } @Override public void inOrder() { Stack<Integer> dataStack = new Stack<Integer>(); int currentNum = 0; String str = " "; while (!dataStack.isEmpty() || elementData[currentNum] != null) { if (checkIndex(currentNum) && elementData[currentNum] != null) { dataStack.push(currentNum); currentNum = (currentNum << 1) + 1; } else { currentNum = dataStack.pop(); str += (elementData[currentNum] + ""); currentNum = (currentNum + 1) << 1; } } System.out.println(str); } @Override public void postORrder() { Set<Integer> visitedSet = new HashSet<Integer>(); Stack<Integer> dataStack = new Stack<Integer>(); int currentNum = 0; String str = " "; while (checkIndex(currentNum) && elementData[currentNum] != null) { while (checkIndex((currentNum << 1) + 1) && elementData[(currentNum << 1) + 1] != null) { dataStack.push(currentNum);//Continue to search left and stop searching once the left node is empty currentNum = (currentNum << 1) + 1; } //(The current node is not empty) and (there is no right child or the right child has been visited) then visit the node while (checkIndex(currentNum) && elementData[currentNum] != null && (!checkIndex(((currentNum + 1) >> 1)) || elementData[(currentNum + 1) << 1] == null || visitedSet.contains(elementData[(currentNum + 1) << 1]))) { str += elementData[currentNum]; str += " "; visitedSet.add(currentNum);//Add to the visited set if (dataStack.isEmpty()) {//The stack is empty and ends directly System.out.println(str); return; } currentNum = dataStack.pop(); } dataStack.push(currentNum); currentNum = (currentNum + 1) << 1;//Go to the right subtree } } @Override public void clear() { root = null; elementData = null; level = 0; } public boolean checkIndex(int index) { return index >= 0 && index <= ((1 << (level + 1)) - 2); } }