题目:二叉树的后序遍历
解析:
1.递归遍历
public List<Integer> postorderTraversal1(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
if (root == null) return list;
postorder(root,list);
return list;
}
public void postorder(TreeNode root, List<Integer> list){
if (root != null){
postorder(root.left,list);
postorder(root.right,list);
list.add(root.val);
}
}
2.非递归遍历
①首先向栈中循环压入左节点,即stack中数据为1->2->4->8;
②判断栈顶结点8是否有右孩子,如果没有弹出8添加到list中,即栈stack中数据为1->2->4,list中数据为8;
③判断栈顶结点4是否有右孩子,结点4有右孩子,将结点4的右孩子9压入栈中,栈stack数据为1->2->4->9;
④判断栈顶结点9是否有右孩子,结点9没有右孩子,弹出结点9加入list中,栈stack中的数据为1->2->4,list中的数据为8->9;
⑤判断栈顶元素4是否有结点,注意此时要加上该节点的右孩子之前是否被访问过的限定条件,即在上一步骤记录弹出的结点last=9。此时由于栈顶4的右孩子被访问过,因此栈顶元素不再加入list中,直接弹出即可;
…
循环判断栈顶元素是否有右孩子或栈顶元素的右孩子是否被访问过,如果有则先压入栈中,如果没有则直接弹出加入list中。
public List<Integer> postorderTraversal2(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
if (root == null) return list;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pnode = null;
while (root != null || !stack.isEmpty()){
//循环将左孩子的结点压入栈
while(root != null){
stack.push(root);
root = root.left;
}
TreeNode node = stack.peek();
//如果栈中压入的结点的右孩子为空,或其右孩子为上一个已经被访问过
if (node.right == null|| node.right == pnode){
list.add(node.val);//直接访问该节点,不在压入其右孩子
pnode = stack.pop();//记录当前被访问过的结点
root = null;
}else{
//如果栈中压入的结点的有右孩子,那么压入右孩子
root = node.right;
}
}
return list;
}