前序遍历:
利用栈实现循环,类似于图的深度优先遍历(DFS)。将根节点入栈,然后只要栈不为空,出栈并访问,接着依次将访问节点的右节点、左节点入栈。
public void preOrder(TreeNode root){
if(root==null)
return;
Stack<TreeNode> s=new Stack<TreeNode>();
s.push(root);
while(!s.isEmpty()){
TreeNode temp=s.pop();
System.out.println(temp.val);
if(temp.right!=null)
s.push(temp.right);
if(temp.left!=null)
s.push(temp.left);
}
}中序遍历:
对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。处理过程如下:
对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束
public void inOrder(TreeNode root){
if(root==null)
return;
Stack<TreeNode> s=new Stack<TreeNode>();
TreeNode node = root;
while(node!=null||!s.isEmpty()){
while(node!=null){
s.push(node);
node=node.left;
}
if(!s.isEmpty()){
node=s.pop();
System.out.println(node.val);
node=node.right;
}
}
}后序遍历:
保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
public void postOrder(TreeNode root)
{
Stack<TreeNode> s=new Stack<TreeNode>();
TreeNode cur = null; //当前结点
TreeNode pre = null; //前一次访问的结点
s.push(root);
while(!s.empty()){
cur=s.peek();
if((cur.left== null && cur.right == null)||
(pre!= null &&(pre==cur.left||pre==cur.right)))
{
//如果当前结点没有孩子结点或者孩子节点都已被访问过
System.out.println(cur.val);
s.pop();
pre=cur;
}
else{
if(cur.left!=null)
s.push(cur.right);
if(cur.left!=null)
s.push(cur.left);
}
}
}层序遍历:
用队列实现,先将根节点入队列,只要队列不为空,然后出队列,并访问,接着讲访问节点的左右子树依次入队列
public static void levelTravel(TreeNode root){
if(root==null)return;
Queue<TreeNode> q=new LinkedList<TreeNode>();
TreeNode node = root;
q.add(node);
while(!q.isEmpty()){
node = q.poll();
System.out.println(node.val);
if(node.left!=null)
q.add(node.left);
if(node.right!=null)
q.add(node.right);
}
}
本文详细介绍了二叉树的四种遍历方法:前序、中序、后序及层序遍历。每种遍历均提供了具体实现代码,帮助读者深入理解二叉树遍历的原理与应用。
1784

被折叠的 条评论
为什么被折叠?



