二叉树的六种遍历方式(其中控制台输出代表访问)
1.递归先序
public void recursion_pre(TreeNode root)
{
if (root==null)
return;
System.out.print(root.val);
recursion_pre(root.left);
recursion_pre(root.right);
}
2.递归中序
public void recursion_in(TreeNode root)
{
if (root==null)
return;
recursion_in(root.left);
System.out.print(root.val);
recursion_in(root.right);
}
3.递归后序
public void recursion_post(TreeNode root)
{
if (root==null)
return;
recursion_post(root.left);
recursion_post(root.right);
System.out.print(root.val);
}
可以看到,使用递归的方法对二叉树进行遍历是非常简单的,缺点就是如果二叉树太过庞大递归层次过深容易导致溢出。下边是借助栈结构实现的非递归方法。
4.非递归先序
非递归先序遍历也很简单,先访问根节点,同时右孩子先入栈,左孩子后入栈
public void noRecursion_pre(TreeNode root)
{
Stack<TreeNode> s=new Stack<>();
if (root!=null)
s.push(root);
while (!s.isEmpty())
{
TreeNode cur=s.pop();
System.out.print(cur.val);
if (cur.right!=null)
s.push(cur.right);
if (cur.left!=null)
s.push(cur.left);
}
}
5.非递归中序
中序遍历是左->根->右,在此过程中我们需两次经过某节点,第一次是为了得到其左孩子,第二次是访问完左孩子进行该节点的访问以及寻找其右孩子。因此先将左孩子依次入栈,直到没有左孩子,此时访问该栈顶节点并对其右孩子循环上边做法。
public void noRecursion_in(TreeNode root)
{
if (root==null)
return;
Stack<TreeNode> s=new Stack<>();
TreeNode cur=root;
while (!s.isEmpty() || cur!=null)
{
while (cur!=null)
{
s.push(cur);
cur=cur.left;
}
if (!s.isEmpty())
{
cur=s.pop();
System.out.print(cur.val);
cur=cur.right;
}
}
}
6.非递归后序
非递归后序实现的办法很多,我这里仅展示较为好理解的双辅助栈法。核心在于在栈1中入栈顺序为根-左-右,在栈2中入栈顺序为根-右-左
public void noRecursion_post(TreeNode root)
{
if(root==null)
return;
Stack<TreeNode> s1 = new Stack<TreeNode>();
Stack<TreeNode> s2 = new Stack<TreeNode>();
TreeNode cur=root;
s1.push(cur);
while(!s1.isEmpty()){
cur=s1.pop();
s2.push(cur);
if (cur.left!=null)
s1.push(cur.left);
if (cur.right!=null)
s1.push(cur.right);
}
while(!s2.isEmpty()){
System.out.print(s2.pop().val);
}
}