traverse binary tree
Traversing a binary tree refers to visiting each node of the binary tree in turn according to a certain rule. The traversing process of the binary tree is the process of arranging the nodes in the non-linear structure of the binary tree in a linear sequence.
public class ThreeLinkBinTree<E> { public static class TreeNode { Object data; TreeNode left; TreeNode right; TreeNode parent; public TreeNode() { } public TreeNode(Object data) { this.data = data; } public TreeNode(Object data, TreeNode left, TreeNode right, TreeNode parent) { this.data = data; this.left = left; this.right = right; this.parent = parent; } } private TreeNode root; // Create binary tree with default constructor public ThreeLinkBinTree() { this.root = new TreeNode(); } // Create a binary tree with the specified root element public ThreeLinkBinTree(E data) { this.root = new TreeNode(data); } /** * Add child nodes to the specified node * @param parent the index of the parent node to which the child node needs to be added * @param data the data of the new child node * @param left is the left node * @return the new node */ public TreeNode addNode(TreeNode parent, E data, boolean left) { if (parent == null) { throw new RuntimeException(parent + "The node is empty, cannot add child nodes"); } if (left && parent.left != null) { throw new RuntimeException(parent + "The node already has a left child, and the left child cannot be added"); } if (!left && parent.right != null) { throw new RuntimeException(parent + "The node already has a right child, and the right child cannot be added"); } TreeNode newNode = new TreeNode(data); if (left) { parent.left = newNode; } else { parent.right = newNode; } newNode.parent = parent; return newNode; } // Check if the binary tree is empty public boolean empty() { // Determine if the binary tree is empty based on the root element return root.data == null; } // return the root node public TreeNode root() { if (empty()) { throw new RuntimeException("The root node is empty"); } return root; } // Returns the parent node of the specified node (non-root node) public E parent(TreeNode node) { if (node == null) { throw new RuntimeException(node + "The node is empty and cannot return its parent"); } return (E)node.parent.data; } // Returns the left child of the specified node (non-leaf). Returns null when the left child node does not exist public E leftChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "node is empty, no left child"); } return parent.left == null? null : (E)parent.left.data; } // Returns the right child of the specified node (non-leaf). Returns null when the right child node exists public E rightChild(TreeNode parent) { if (parent == null) { throw new RuntimeException(parent + "node is empty, no right child"); } return parent.right == null? null : (E)parent.right.data; } // return the depth of the binary tree public int deep() { // Get the depth of the tree return deep(root); } // recursive method: the depth of each subtree is the maximum depth of all subtrees + 1 private int deep(TreeNode node) { if (node == null) { return 0; } if (node.left == null && node.right == null) { return 1; } else { int leftDeep = deep(node.left); int rightDeep = deep(node.right); int max = leftDeep > rightDeep? leftDeep : rightDeep; return max + 1; } } // implement preorder traversal public List<TreeNode> preIterator() { return preIterator(root); } private List<TreeNode> preIterator(TreeNode node) { List<TreeNode> list = new ArrayList<TreeNode>(); list.add(node); if (node.left != null) { list.addAll(preIterator(node.left)); } if (node.right != null) { list.addAll(preIterator(node.right)); } return list; } // implement in-order traversal public List<TreeNode> inIterator() { return inIterator (root); } private List<TreeNode> inIterator(TreeNode node) { List<TreeNode> list = new ArrayList<TreeNode>(); if (node.left != null) { list.addAll(inIterator(node.left)); } list.add(node); if (node.right != null) { list.addAll(inIterator(node.right)); } return list; } public List<TreeNode> postIterator() { return postIterator(root); } // implement post-order traversal private List<TreeNode> postIterator(TreeNode node) { List<TreeNode> list = new ArrayList<TreeNode>(); if (node.left != null) { list.addAll(postIterator(node.left)); } if (node.right != null) { list.addAll(postIterator(node.right)); } list.add(node); return list; } // breadth-first traversal public List<TreeNode> breadthFirst() { Queue<TreeNode> queue = new ArrayDeque<TreeNode>(); List<TreeNode> list = new ArrayList<TreeNode>(); if (root != null) { queue.offer(root); } while (!queue.isEmpty()) { list.add(queue.peek()); TreeNode node = queue.poll(); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } return list; } }
public class ThreeLinkBinTreeTest { public static void main(String[] args) { ThreeLinkBinTree<String> binTree = new ThreeLinkBinTree("根节点"); ThreeLinkBinTree.TreeNode tn1 = binTree.addNode(binTree.root(), "二左", true); ThreeLinkBinTree.TreeNode tn2 = binTree.addNode(binTree.root(), "二右", false); ThreeLinkBinTree.TreeNode tn3 = binTree.addNode(tn1, "三左", true); ThreeLinkBinTree.TreeNode tn4 = binTree.addNode(tn1, "三右", false); ThreeLinkBinTree.TreeNode tn5 = binTree.addNode(tn3, "四右", false); ThreeLinkBinTree.TreeNode tn6 = binTree.addNode(tn5, "五左", true); ThreeLinkBinTree.TreeNode tn7 = binTree.addNode(tn5, "五右", false); System.out.println("[Pre-order traversal]: " + binTree.preIterator()); System.out.println("[Inorder traversal]:" + binTree.inIterator()); System.out.println("[Post-order traversal]: " + binTree.postIterator()); System.out.println("[Breadth first traversal]:" + binTree.breadthFirst()); } }