(1)、实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式
1)递归方式
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
/**
* 先序遍历
* */
public static void preOrder(Node node) {
if (node == null) {
return;
}
System.out.print(node.value + "\t");
preOrder(node.left);
preOrder(node.right);
}
/**
* 中序遍历
* */
public static void middleOrder(Node node){
if(node == null){
return;
}
middleOrder(node.left);
System.out.print(node.value + "\t");
middleOrder(node.right);
}
/**
* 后序遍历
* */
public static void postOrder(Node node){
if(node == null){
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.print(node.value + "\t");
}
2)非递归方式
public static void main(String[] args) {
Node node = new Node(1);
node.left = new Node(2);
node.left.left = new Node(3);
node.left.right = new Node(4);
node.left.right.left = new Node(5);
node.right = new Node(6);
node.right.left = new Node(7);
node.right.right = new Node(8);
postOrder(node);
}
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
/**
* 先序遍历
*/
public static void preOrder(Node node) {
if (node == null) {
return;
}
Stack<Node> stack = new Stack<Node>();
stack.push(node);
while (!stack.empty()) {
node = stack.pop();
System.out.print(node.value + "\t");
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
}
/**
* 中序遍历
* 思想:(1)将node的左子树压入,node指向node的左子树
* (2)node非空则继续第一步,node指向为空则取出栈顶并打印它的值,并指向node的右子树。
*/
public static void middleOrder(Node node) {
if (node == null) {
return;
}
Stack<Node> stack = new Stack<Node>();
while (!stack.empty() || node != null) {
if (node != null) {
stack.push(node);
node = node.left;
} else {
node = stack.pop();
System.out.print(node.value + "\n");
node = node.right;
}
}
}
/**
* 后序遍历
*/
public static void postOrder(Node node) {
if (node == null) {
return;
}
Stack<Node> stack = new Stack<Node>();
Stack<Node> stackM = new Stack<Node>();
stack.push(node);
while (!stack.isEmpty()) {
node = stack.pop();
stackM.push(node);
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
while (!stackM.isEmpty()) {
System.out.print(stackM.pop().value + "\t");
}
}
3)用一个栈实现后序遍历
/**
* 后序遍历打印一颗二叉树
* */
public static void main(String[] args) {
Node node = new Node(1);
node.left = new Node(2);
node.left.left = new Node(3);
node.left.right = new Node(4);
node.left.right.left = new Node(5);
node.right = new Node(6);
node.right.left = new Node(7);
node.right.right = new Node(8);
posOrder(node);
}
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
/**
* 用一个栈实现后序遍历
* */
public static void posOrder(Node h) {
if (h == null) {
return;
}
Stack<Node> stack = new Stack<Node>();
stack.push(h);
Node c = null;
//打印左右中
//c代表栈顶的节点,h代表最近一次弹出并打印的节点,初始时h为头结点c为null
while (!stack.isEmpty()) {
//每次令c当前stack的栈顶节点,但是不从stack弹出,此时分为以下三种情况
c = stack.peek();
if (c.left != null && h != c.left && h != c.right) {//排除了左子树没有入栈的情况
/*h是最近一次弹出并打印的节点,所以如果h等于c的左孩子或者右孩子节点,说明c
的左子树与右子树已经打印完毕,此时不应该再将c的左孩子节点放入stack中。
否则,说明左子树还没处理过,那么此时将c的左孩子节点压入stack之中*/
stack.push(c.left);
} else if (c.right != null && h != c.right) {//排除了右子树没有入栈的情况
//说明右子树还没处理过,此时将c的右孩子节点压入stack
stack.push(c.right);
} else {
//说明c的左子树和右子树都已经打印完毕,则弹出首节点
System.out.print(stack.pop().value + " ");
h = c;
}
}
System.out.println();
}