/**
* 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
* 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
* 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},
* 则重建二叉树并返回根结点。
*
* 前序遍历preorder(深度优先遍历depth-first traversal):根、左、右
* 中序遍历inorder:左、根、右
* 后序遍历postorder:左、右、根
*/
public class E6 {
public static void main(String[] args) {
int preorder[] = {1,2,4,7,3,5,6,8};
int inorder[] = {4,7,2,1,5,3,8,6};
try {
BinaryTreeNode root = constructTree(preorder, inorder);
System.out.println("前序遍历:");
preorderTraversalRecursively(root);
System.out.println();
preorderTraversalNonRecursively(root);
System.out.println();
System.out.println("中序遍历:");
inorderTraversalRecursively(root);
System.out.println();
inorderTraversalNonRecursively(root);
System.out.println();
System.out.println("后序遍历:");
postorderTraversalRecursively(root);
System.out.println();
postorderTraversalNonRecursively(root);
System.out.println();
System.out.println("宽度优先遍历:");
breadthFirstTraversal(root);
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
private static BinaryTreeNode constructTree(int[] preorder, int[] inorder) throws Exception {
if (preorder == null || inorder == null
|| preorder.length == 0 || inorder.length!=preorder.length) {
throw new Exception("Invalid input");
}
BinaryTreeNode root = constructRecursively(preorder, 0, preorder.length-1,
inorder, 0, inorder.length-1);
return root;
}
private static BinaryTreeNode constructRecursively(int[] preorder, int preStart,
int preEnd, int[] inorder, int inStart, int inEnd) throws Exception {
if (preStart>preEnd || inStart>inEnd || preEnd-preStart != inEnd-inStart) {
return null;
}
BinaryTreeNode root = new BinaryTreeNode(preorder[preStart]);
// 在中序遍历中找到该根节点,分成左右两个子树
int inorderRootIndex = inStart;
while (inorderRootIndex<=inEnd){
if (inorder[inorderRootIndex] == root.getValue()) {
break;
}
inorderRootIndex++;
}
if (inorderRootIndex>inEnd) {
throw new Exception("Invalid input");
}
int leftLength = inorderRootIndex-inStart;
root.setLeftNode(constructRecursively(preorder,preStart+1,preStart+leftLength,
inorder,inStart,inorderRootIndex-1));
root.setRightNode(constructRecursively(preorder, preStart+leftLength+1, preEnd,
inorder,inorderRootIndex+1,inEnd));
return root;
}
// 后序遍历(递归实现)
private static void postorderTraversalRecursively(BinaryTreeNode root) {
if (root == null) return;
postorderTraversalRecursively(root.getLeftNode());
postorderTraversalRecursively(root.getRightNode());
System.out.print(root.getValue()+" ");
}
/**
* 后序遍历(非递归实现)
* 从根开始,将所有左子树入栈
* peek栈顶节点,
* 1)该节点有右子树,从右子树开始,将其所有左子树入栈
* 2)该节点没有右子树,pop该节点并打印,若该节点是当前新栈顶的右子树,pop并打印,循环...
*/
private static void postorderTraversalNonRecursively(BinaryTreeNode root) {
if (root == null) return;
Stack<BinaryTreeNode> stack = new Stack<>();
BinaryTreeNode current = root;
do {
stack.push(current);
current = current.getLeftNode();
} while (current != null);
while (!stack.isEmpty()) {
if (stack.peek().getRightNode() != null) {
current = stack.peek().getRightNode();
do {
stack.push(current);
current = current.getLeftNode();
} while (current != null);
} else {
do {
current = stack.pop();
System.out.print(current.getValue()+" ");
}while (!stack.isEmpty() && current.equals(stack.peek().getRightNode()));
}
}
}
// 中序遍历
private static void inorderTraversalRecursively(BinaryTreeNode root) {
if (root == null) return;
inorderTraversalRecursively(root.getLeftNode());
System.out.print(root.getValue()+" ");
inorderTraversalRecursively(root.getRightNode());
}
/**
* 中序遍历(非递归实现)
* 从根开始,将所有左子树入栈
* 遍历栈顶节点,输出值,从右子树开始,将其所有左子树入栈
*/
private static void inorderTraversalNonRecursively(BinaryTreeNode root) {
if (root == null) return;
Stack<BinaryTreeNode> stack = new Stack<>();
BinaryTreeNode current = root;
do {
stack.push(current);
current = current.getLeftNode();
} while(current != null);
while (!stack.isEmpty()) {
BinaryTreeNode node = stack.pop();
System.out.print(node.getValue()+" ");
if (node.getRightNode() != null) {
current = node.getRightNode();
do {
stack.push(current);
current = current.getLeftNode();
}while (current!=null);
}
}
}
// 前序遍历(深度优先遍历)
private static void preorderTraversalRecursively(BinaryTreeNode root) {
if (root == null) return;
System.out.print(root.getValue()+" ");
preorderTraversalRecursively(root.getLeftNode());
preorderTraversalRecursively(root.getRightNode());
}
/**
* 前序遍历(非递归实现)
* 栈辅助,将根节点入栈,pop栈顶元素直至栈为空
* 对于每个栈顶元素,先将其右子树入栈,再将其左子树入栈
*/
private static void preorderTraversalNonRecursively(BinaryTreeNode root) {
if (root == null) return;
Stack<BinaryTreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
BinaryTreeNode node = stack.pop();
System.out.print(node.getValue()+" ");
if (node.getRightNode() != null) {
stack.push(node.getRightNode());
}
if (node.getLeftNode()!= null) {
stack.push(node.getLeftNode());
}
}
}
//宽度优先遍历
private static void breadthFirstTraversal(BinaryTreeNode root) {
if (root == null) return;
Queue<BinaryTreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
BinaryTreeNode node = queue.poll();
System.out.printf("%d ",node.getValue());
if (node.getLeftNode() != null) {
queue.add(node.getLeftNode());
}
if (node.getRightNode() != null) {
queue.add(node.getRightNode());
}
}
}
}
class BinaryTreeNode {
private int value;
private BinaryTreeNode leftNode;
private BinaryTreeNode rightNode;
public BinaryTreeNode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BinaryTreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(BinaryTreeNode leftNode) {
this.leftNode = leftNode;
}
public BinaryTreeNode getRightNode() {
return rightNode;
}
public void setRightNode(BinaryTreeNode rightNode) {
this.rightNode = rightNode;
}
}
剑指offer E6 根据前序和中序重构二叉树
于 2022-02-17 00:40:07 首次发布