算法准备-5.4
1. 根据二叉树的前序序列和中序序列确定二叉树
-
描述:根据一棵树的前序遍历与中序遍历构造二叉树。
-
思路:递归,前序序列的第一个元素为根节点,找出此节点在中序序列中的位置,左右两边分别为根结点的左右子树,分别对其进行构造即可。(注意边界条件)
-
题解:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { if (preorder == null || preorder.length == 0 || inorder == null || inorder.length == 0 || preorder.length != inorder.length) { return null; } return PreinCreate(preorder,inorder,0,preorder.length-1,0,inorder.length-1); } public TreeNode PreinCreate(int[] preorder,int[] inorder,int l1,int h1,int l2,int h2) { if(l1>h1||l2>h2) { return null; } TreeNode root=new TreeNode(preorder[l1]); int node=preorder[l1]; int i=0; while(inorder[l2+i]!=node) { i++; } root.left=PreinCreate(preorder,inorder,l1+1,l1+i,l2,l2+i-1); root.right=PreinCreate(preorder,inorder,l1+i+1,h1,l2+i+1,h2); return root; } }
2. 二叉树的后序遍历的非递归算法
-
描述:输出二叉树的后序遍历序列
-
思路:先递归左子树,全部入栈,用一个指针指向前一个访问过的节点,只有当节点的右子树不存在或者右子树被访问过,也就是pre是当前栈顶的右节点,这时将此节点从栈顶弹出,并访问他,因为此时说明他的子树已经全部访问完毕,将遍历指针重置成null
-
题解:
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ //没有利用前序遍历,真正的非递归后序遍历 class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> res=new ArrayList<>(); Stack<TreeNode> stack=new Stack<>(); TreeNode p=root; TreeNode pre=null; while(p!=null||!stack.isEmpty()) { if(p!=null) { stack.push(p); p=p.left; } else { p=stack.peek(); if(p.right!=null&&p.right!=pre) { p=p.right; } else { stack.pop(); res.add(p.val); pre=p; p=null; } } } return res; } }