前序遍历:首先读取根节点,再读取左孩子,再读取右孩子
中序遍历:首先读取左孩子,再读取根节点,再读取右孩子
后序遍历:首先读取左孩子,再读取右孩子,再读取根节点
代码实现:
节点类:
package org.nix.tree.binary; /** * Create by [email protected] on 2018/5/4. * 二叉树节点 */ public class TreeNode<T> { private T data; private TreeNode lightNode; private TreeNode rightNode; /** * 创建有左右子节点的节点 * 若没有孩子则设为null * @param data 该节点拥有的数据 * @param lightNode 左孩子 * @param rightNode 右孩子 */ public TreeNode(T data, TreeNode lightNode, TreeNode rightNode) { this.data = data; this.lightNode = lightNode; this.rightNode = rightNode; } /** * 只有数据的节点 * @param data 该节点拥有的数据 */ public TreeNode(T data) { this.data = data; } public T getData() { return data; } public void setData(T data) { this.data = data; } public TreeNode getLightNode() { return lightNode; } public void setLightNode(TreeNode lightNode) { this.lightNode = lightNode; } public TreeNode getRightNode() { return rightNode; } public void setRightNode(TreeNode rightNode) { this.rightNode = rightNode; } @Override public String toString() { return "TreeNode{" + "data=" + data + ", lightNode=" + lightNode + ", rightNode=" + rightNode + '}'; } }
遍历方法抽象:
package org.nix.tree.base; /** * Create by [email protected] on 2018/5/4. * * 遍历方法抽象 */ public interface Traverse <T>{ /** * 前序遍历 * @param root 遍历节点 */ void preorder(T root); /** * 中序遍历 * @param root 遍历节点 */ void inorder(T root); /** * 后序遍历 * @param root 遍历节点 */ void postorder(T root); /** * 广度遍历 * @param root 遍历节点 */ void layerOrder(T root); /** * 深度遍历 * @param root 遍历节点 */ void deepOrder(T root); }
遍历方法部分实现及描述
import org.nix.tree.base.Traverse; import org.nix.tree.binary.TreeNode; import java.util.Stack; /** * Create by [email protected] on 2018/5/4. * <p> * 栈遍历二叉树 */ public abstract class AbstractStackTraverse implements Traverse<TreeNode> { /** * 1.入栈root节点 * 2.输出头节点,判断是否有左右节点,如有先入右节点再入左节点 * 3.若栈空,则全部遍历完 * * @param root 遍历节点 */ @Override public void preorder(TreeNode root) { Stack stack = getStack(); if (root != null) { stack.push(root); } System.out.print("前序遍历: "); while (!stack.isEmpty()) { TreeNode treeNode = (TreeNode) stack.pop(); System.out.print(treeNode.getData() + " "); if (treeNode.getRightNode() != null) stack.push(treeNode.getRightNode()); if (treeNode.getLightNode() != null) stack.push(treeNode.getLightNode()); } } /** * 1.将节点的所有左节点栈入 * 2.栈出一个节点,输出值,判断是否有右节点,若存在,将该节点的所有做节点全出入栈 * 3.若不存在右节点,则栈出下一个节点,输出值 * 4.直到root == null 和 栈空 * * @param root 遍历节点 */ @Override public void inorder(TreeNode root) { Stack stack = getStack(); System.out.print("中序遍历: "); while (root != null || !stack.isEmpty()) { while (root != null) { stack.push(root); root = root.getLightNode(); } if (!stack.isEmpty()) { TreeNode treeNode = (TreeNode) stack.pop(); System.out.print(treeNode.getData() + " "); root = root.getRightNode(); } } } /** * 如果节点不为空,则压栈,进入输入栈和输出栈,并将当前节点重置为当前节点的右孩子 * 如果节点为空,则输入栈弹出,取弹出的节点的左孩子为当前节点 * 直到输入栈为空且节点为null * @param root 遍历节点 */ @Override public void postorder(TreeNode root) { Stack input = getStack(); Stack output = getStack(); // 中间栈存储逆后序遍历结果 while (root!=null || !input.isEmpty()){ if (root != null) { output.push(root); input.push(root); root = root.getRightNode(); } else { root = (TreeNode) input.pop(); root = root.getLightNode(); } } while (!output.isEmpty()) { TreeNode treeNode = (TreeNode) output.pop(); System.out.println(treeNode.getData()); } } abstract Stack getStack(); }