第一行输入两个整数 n 和 root,n 表示二叉树的总节点个数,root 表示二叉树的根节点。
以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)
输出三行分别表示二叉树的前序,中序和后序遍历。
3 1 1 2 3 2 0 0 3 0 0
1 2 3 2 1 3 2 3 1
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.HashMap; class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int val) { this.val = val; } } public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 构建二叉树 String[] params = br.readLine().split(" "); int n = Integer.parseInt(params[0]); TreeNode root = new TreeNode(Integer.parseInt(params[1])); HashMap<Integer, TreeNode> map = new HashMap<>(); map.put(root.val, root); for(int i = 0; i < n; i++){ params = br.readLine().split(" "); int val = Integer.parseInt(params[0]); int leftVal = Integer.parseInt(params[1]); int rightVal = Integer.parseInt(params[2]); TreeNode node = map.get(val); if(leftVal != 0) { node.left = new TreeNode(leftVal); map.put(leftVal, node.left); } if(rightVal != 0) { node.right = new TreeNode(rightVal); map.put(rightVal, node.right); } } // 三种遍历 preOrder(root); inOrder(root); postOrder(root); } private static void preOrder(TreeNode root) { if(root == null) return; TreeNode cur = root; TreeNode mostRight = null; while(cur != null){ mostRight = cur.left; if(mostRight != null){ // 到左子树的最右节点 while(mostRight.right != null && mostRight.right != cur) mostRight = mostRight.right; if(mostRight.right == null){ System.out.print(cur.val + " "); // 第一次到左子树的最右节点,需要将其右孩子的指向指向cur mostRight.right = cur; cur = cur.left; continue; }else{ // 第二次到这要回复右孩子的指针 mostRight.right = null; } }else{ // 只会到一次的节点,直接打印 System.out.print(cur.val + " "); } // 没有左子树节点直接右移 cur = cur.right; } System.out.println(); } private static void inOrder(TreeNode root) { if(root == null) return; TreeNode cur = root; TreeNode mostRight = null; while(cur != null){ mostRight = cur.left; if(mostRight != null){ // 到左子树的最右节点 while(mostRight.right != null && mostRight.right != cur) mostRight = mostRight.right; if(mostRight.right == null){ // 第一次到左子树的最右节点,需要将其右孩子的指向指向cur mostRight.right = cur; cur = cur.left; continue; }else{ System.out.print(cur.val + " "); // 第二次到这要回复右孩子的指针 mostRight.right = null; } }else{ // 只会到一次的节点,直接打印 System.out.print(cur.val + " "); } // 没有左子树节点直接右移 cur = cur.right; } System.out.println(); } private static void postOrder(TreeNode root) { if(root == null) return; TreeNode cur = root; TreeNode mostRight = null; while(cur != null){ mostRight = cur.left; if(mostRight != null){ // 到左子树的最右节点 while(mostRight.right != null && mostRight.right != cur) mostRight = mostRight.right; if(mostRight.right == null){ // 第一次到左子树的最右节点,需要将其右孩子的指向指向cur mostRight.right = cur; cur = cur.left; continue; }else{ // 第二次到这要回复右孩子的指针 mostRight.right = null; printEdge(cur.left); // 逆序打印左树右边界 } } // 没有左子树节点直接右移 cur = cur.right; } // 遍历完成后还需要打印整棵树的右边界 printEdge(root); System.out.println(); } private static void printEdge(TreeNode node) { TreeNode tail = reverseEdge(node); TreeNode cur = tail; while(cur != null){ System.out.print(cur.val + " "); cur = cur.right; } // 逆序打印后还要把指针指向还原回去 reverseEdge(tail); } // 翻转链表操作 private static TreeNode reverseEdge(TreeNode cur) { TreeNode prev = null; TreeNode next = null; while(cur != null){ next = cur.right; cur.right = prev; prev = cur; cur = next; } return prev; } }