前序遍历:首先读取根节点,再读取左孩子,再读取右孩子
中序遍历:首先读取左孩子,再读取根节点,再读取右孩子
后序遍历:首先读取左孩子,再读取右孩子,再读取根节点
代码实现:
节点类:
package org.nix.tree.binary;
/**
* Create by zhangpe0312@qq.com 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 zhangpe0312@qq.com 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 zhangpe0312@qq.com 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();
}