二叉树的遍历总结
Posted 最帅的芝士
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的遍历总结相关的知识,希望对你有一定的参考价值。
首先需要明白二叉树的遍历方式(先序,中序,后序);
无论哪种遍历方式,考查节点的顺序都是一样的,只不过有时候考查了节点,将其暂存,需要在之后的过程中输出。
先序:考查到第一个节点后,就即刻输出该节点的值,并继续遍历该节点的左右子树(根的左右子树)。
中序:考查到第一个节点后,先将该节点的值暂存起来,然后遍历完其左子树后,再输出该节点的值,然后遍历右子树。
后序:考查到第一个节点后,先将该节点的值暂存起来,然后遍历完左右子树后,再输出该节点的值。
先序:1,2,4,6,7,8,3,5
中序:4,7,6,8,2,1,3,5
后序:7,8,6,4,2,5,3,1
二叉树代码的实现:
先序遍历的递归实现:先输出节点的值,再遍历左右子树,中序遍历和后序遍历的递归类似,修改节点的输出位置即可。
//递归先序遍历
public static void recursionPreorderTraversal(TreeNode root){
if (root !=null){
System.out.println(root.val + "-----");
recursionPreorderTraversal(root.left);
recursionPreorderTraversal(root.right);
}
}
非递归实现先序遍历:需要用一个栈来暂存访问过的节点
//非递归实现先序遍历
public static void preorderTraversal(TreeNode root){
//用来暂存节点的栈
Stack<TreeNode> nodeStack = new Stack<>();
TreeNode node = root;
//当遍历到最后一个节点时,无论它的左右子树都为空,并且栈也为空
//所以只要不同时满足这俩条件,都需要进入循环
while (node !=null || !nodeStack.isEmpty()){
while (node !=null){
System.out.println(node.val + "-------");
//为了找到该节点右子树,将该节点暂存.
nodeStack.add(node);
node = node.left;
}
//一直到左子树为空,才开始考虑右子树
//如果栈已空,则不需要再考虑
//弹出栈顶元素,将游标指向该元素的右子树
if (!nodeStack.isEmpty()){
node = nodeStack.pop();
node = node.right;
}
}
}
中序遍历
//递归中序遍历
public static void recursionMiddleTraversal(TreeNode root){
if (root !=null){
recursionMiddleTraversal(root.left);
System.out.println(root.val + "-----");
recursionMiddleTraversal(root.right);
}
}
中序遍历的非递归实现
//非递归实现中序遍历
public static void middleTraversal(TreeNode root){
TreeNode node = root;
Stack<TreeNode> nodeStack = new Stack<>();
while (node !=null || !nodeStack.isEmpty()){
while (node !=null){
nodeStack.add(node);
node = node.left;
}
if (!nodeStack.isEmpty()){
node = nodeStack.pop();
System.out.println(node.val + "---------");
node = node.right;
}
}
}
后序遍历
//递归后序遍历
public static void recursionPostorerTraversal(TreeNode root){
if (root !=null){
recursionPostorerTraversal(root.left);
recursionPostorerTraversal(root.right);
System.out.println(root.val + "---------");
}
}
后序遍历的非递归实现:
后序遍历在决定是否可以输出当前节点的值的时候,需要考虑其左右子树是否都已经遍历完成,所以需要设置一个lastVist游标,若lastVist等于当前考查节点的右子树,表示该节点的左右子树都已经遍历完成,可以输出当前节点。并把lastVist节点设置成当前节点,将当前游标节点node设置为空,下一轮就可以访问栈顶元素。否则接着考虑右子树的。
public static void postorderTraversal(TreeNode root){
Stack<TreeNode> nodeStack = new Stack<>();
TreeNode node = root;
TreeNode lastIndex = root;
while (node !=null || !nodeStack.isEmpty()){
while (node.left !=null){
nodeStack.add(root.left);
}
//查看当前栈顶元素
node = nodeStack.peek();
//如果其右子树也为空,或者右子树已访问
if (node.right ==null || node.right == lastIndex){
System.out.println(node.val + "----------");
nodeStack.pop();
lastIndex = node;
node =null;
}else {
//否则遍历右子树
node = node.right;
}
}
}
以上是关于二叉树的遍历总结的主要内容,如果未能解决你的问题,请参考以下文章