今天复习了二叉搜索树的创建,二叉树的前、中、后序遍历递归与非递归的实现,按层遍历等等。其中较难的是二叉树的后序遍历过程
因此单独拿出来详细分析一下过程,以及在这个过程中我踩得一些坑
/** * 后序非递归遍历 * @param root */ /** * 思路:首先要搞清楚什么时候才能输出根节点的值,必须等到左节点和右节点都访问完的情况才能访问根节点 * 因此,访问根节点的情况有两种: * 一、当前节点的左右子树都为null时,可以直接访问根节点 * 二、当前节点的左右子树都访问过时,则可以直接访问根节点 * 则可以设置一个标志,让他标识上一个访问的结点 * 遍历栈时,得到栈顶元素,判断他的左右子树为空或者pre标志是否等于当前结点的左右孩子的其中一个时, * 当这两种情况满足其中一种,则就可以访问当前根节点。 * * 至于为什么要判断pre标志是否等于当前结点的左右孩子的其中一个,而不是判断它是否等于当前结点的右孩子? * 原因是这样的:因为可能存在这样一种情况,当前结点只有左孩子结点,则如果去判断它是否等于当前结点的右孩子结点 * 得到的一定是false,这样当前结点永远都不会被访问,并且会陷入死循环,左孩子一直循环入栈的情况。当根结点左 * 子树访问完,如果存在右子树,则会从栈顶得到右子树结点,而此时pre标志等于根节点的左子女,因此第二个条件不成立( * 即pre不会等于根节点右子女的任何一个子女结点) * * LinkedList有一个坑:push操作实际掉的addFirst方法,而pop方法实际掉的是removeFirst方法,链表头是栈顶!!并不是链表尾 */ public static void endPrintTreeNo(TreeNode root) { if(root==null)return; LinkedList<TreeNode> stack=new LinkedList<>(); stack.push(root); TreeNode pre=null,cur=null; while(!stack.isEmpty()) { cur=stack.getFirst(); if((cur.left==null&&cur.right==null)||(pre!=null&&(pre==cur.left||pre==cur.right))){ System.out.print(cur.val+" "); stack.pop(); pre=cur; } else { if(cur.right!=null) stack.push(cur.right); if(cur.left!=null) stack.push(cur.left); } } }