首先给出二叉树的定义:
public class BinaryNode {
int element;
BinaryNode leftChild;
BinaryNode rightChild;
public BinaryNode(int element){
this.element = element;
}
public String toString() {
return "BinaryNode [element=" + element + ", left=" + leftChild + ", right=" + rightChild
+ "]";
}
}
然后是三种遍历方法的递归与非递归实现:
import java.util.Stack;
public class TreeOrder {
public static void main(String[] args) {
BinaryNode[] node = new BinaryNode[10];
for (int i = 0; i <10 ; i++) {
node[i] = new BinaryNode(i);
}
for (int i = 0; i <10 ; i++) {
if(i*2+1<10){
node[i].leftChild = node[2*i+1];
}
if(i*2+2<10){
node[i].rightChild = node[2*i+2];
}
}
//preorder(node[0]);
//midorder(node[0]);
lateorder(node[0]);
}
//前序递归做法
public static void preorderDigui(BinaryNode node){
System.out.println(node.element);
BinaryNode leftNode = node.leftChild;
BinaryNode rightNode = node.rightChild;
if (leftNode!=null)
preorderDigui(leftNode);
if (rightNode!=null)
preorderDigui(rightNode);
}
//前序非递归(使用栈)
public static void preorder(BinaryNode node){
Stack<BinaryNode> stack = new Stack<>();
while (node!=null||!stack.isEmpty()){
while (node!=null){
System.out.println(node.element);
stack.push(node);
node = node.leftChild;
}
if (!stack.isEmpty()){
node = stack.pop();
node = node.rightChild;
}
}
}
//中序递归
public static void midorderDigui(BinaryNode node){
if (node.leftChild!=null)
midorderDigui(node.leftChild);
System.out.println(node.element);
if (node.rightChild!=null)
midorderDigui(node.rightChild);
}
//中序非递归
public static void midorder(BinaryNode node){
Stack<BinaryNode> stack = new Stack<>();
while (node!=null||!stack.isEmpty()){
while (node!=null){
stack.push(node);
node= node.leftChild;
}
if (!stack.isEmpty()){
node = stack.pop();
System.out.println(node.element);
node = node.rightChild;
}
}
}
//后续递归
public static void lateorderDigui(BinaryNode node){
if (node!=null){
if (node.leftChild!=null)
lateorderDigui(node.leftChild);
if (node.rightChild!=null)
lateorderDigui(node.rightChild);
System.out.println(node.element);
}
}
/* 后序遍历的非递归算法是三种顺序中最复杂的,原因在于,后序遍历是先访问左、右子树,再访问根节点,而在非递归算法中,
利用栈回退到时,并不知道是从左子树回退到根节点,还是从右子树回退到根节点,如果从左子树回退到根节点,此时就应该去访问右子树,
而如果从右子树回退到根节点,此时就应该访问根节点。所以相比前序和后序,必须得在压栈时添加信息,以便在退栈时可以知道是从左子树返回,
还是从右子树返回进而决定下一步的操作。*/
//添加信息的方法:创建一个辅助栈,当左子树的点压入,辅助栈压入1,当右子树的点压入,辅助栈压入2
public static void lateorder(BinaryNode node) {
int left = 1;
int right = 2;
Stack<BinaryNode> stack = new Stack<>();
Stack<Integer> stack1 = new Stack<>();
while (node != null || !stack.isEmpty())
{
while (node!=null){
stack.push(node);
stack1.push(left);
node = node.leftChild;}
while (!stack.isEmpty() && stack1.peek() == right) {
stack1.pop();
System.out.println(stack.pop().element);
}
if (!stack.isEmpty() && stack1.peek() == left) {
stack1.pop();
stack1.push(right);
node = stack.peek().rightChild;
}
}
}
}