Java 二叉树的前序、中序、后续遍历 递归和迭代实现

本文详细介绍了二叉树的前序、中序和后序遍历算法,包括递归和迭代两种实现方式,并提供了具体的Java代码示例。

1.前序

递归

 

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<Integer>();
        if(root!=null){
        	list.add(root.val);
        	list.addAll(preorderTraversal(root.left));
        	list.addAll(preorderTraversal(root.right));
        }	
        return list;
    }

迭代

前序就是深度优先遍历,使用stack。

 

	public List<Integer> preorderTraversal(TreeNode root) {
		List<Integer> result=new ArrayList<Integer>();
		Stack<TreeNode> stack=new Stack<>();		
		if(root==null)
			return result;
		stack.push(root);
		while(!stack.isEmpty()){
			TreeNode pNode=stack.pop();			
			result.add(pNode.val);
			if(pNode.right!=null)
				stack.push(pNode.right);
			if(pNode.left!=null)
				stack.push(pNode.left);
		}
		return result;
	}

 

 

 

 

 

另一种写法

 

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<Integer>();
        Stack<TreeNode> s=new Stack<>();
        TreeNode top=root;
        while(top!=null || !s.isEmpty()){
        	while(top!=null){
            	list.add(top.val);
        		s.push(top);
        		top=top.left;
        	}
        	top=s.pop();
        	top=top.right;
        }
        return list;
    }

 

 

 

 

 

2.中序

递归

 

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<Integer>();
        if(root!=null){
            list.addAll(inorderTraversal(root.left));
            list.add(root.val);
            list.addAll(inorderTraversal(root.right));
        }
        return list;
    }


迭代:

 

 

    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<Integer>();
        Stack<TreeNode> s=new Stack<>();
        TreeNode top=root;
        while(top!=null || !s.isEmpty()){
        	while(top!=null){
        		s.push(top);
        		top=top.left;
        	}	
        	top=s.pop();
        	list.add(top.val);     
        	top=top.right;
        }
        return list;
    }

3.后序

 

递归:

 


  public List<Integer> postorderTraversal(TreeNode root) {
  List<Integer> list=new ArrayList<Integer>();
    if(root!=null){
      postorderTraversal(root.left);
      postorderTraversal(root.right);
      list.add(root.val);  
    }
     return list;
 }


迭代:

 

后序的迭代比较麻烦,输出的条件是

1.此节点是叶子节点。

2.此节点的叶子节点都已经输出

所以用一个pre节点保存上一次访问的节点。

 

public List<Integer> postOrderTrace(Tree root) {
		List<Integer> list = new ArrayList<Integer>();
		Stack<Tree> s = new Stack<>();
		Tree top = root;
		Tree pre=null;
		while (top != null || !s.isEmpty()) {
			while (top != null) {
				s.push(top);
				top = top.left;
			}
			top = s.peek();
			if (top.right != null && pre != top.right) {
				top = top.right;
			} else {
				top = s.pop();
				list.add(top.val);
				pre = top;
				top = null;
			}
			
		}
		return list;
	}

// 或者    
public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list=new ArrayList<Integer>();
        if(root==null)
            return list;
        Stack<TreeNode> s=new Stack<>();
        s.push(root);
        TreeNode top,pre=null;
        while(!s.isEmpty()){
        	top=s.peek();
        	if((top.left==null && top.right==null ) || (pre!=null && (top.left==pre || top.right==pre))){
        		list.add(top.val);
        		s.pop();
        	}else{
        		if(top.right!=null){        		
        			s.push(top.right);
        		}	
        		if(top.left!=null){
        			s.push(top.left);
        		}	
        	}	        
        	pre=top;
        }
        return list;
    }

 

 

 

 

 

 

 

### Java二叉树前序、中后序遍历方法及实现 #### 一、基本概念 在二叉树遍历过程中,主要涉及三种方式:前序遍历(Pre-order Traversal)、中遍历(In-order Traversal)以及后序遍历(Post-order Traversal)。每种遍历方式都遵循特定的访问顺[^1]。 - **前序遍历**:按照“根 -> 左子树 -> 右子树”的顺进行访问。 - **中遍历**:按照“左子树 -> 根 -> 右子树”的顺进行访问。 - **后序遍历**:按照“左子树 -> 右子树 -> 根”的顺进行访问。 #### 二、递归实现 以下是基于递归的方式分别实现前序、中后序遍历的方法: ```java class TreeNode { char val; TreeNode left, right; TreeNode(char item) { val = item; left = right = null; } } public class BinaryTreeTraversal { // 前序遍历 public void preOrder(TreeNode node) { if (node == null) { return; } System.out.print(node.val + " "); // 访问当前节点 preOrder(node.left); // 遍历左子树 preOrder(node.right); // 遍历右子树 } // 中遍历 public void inOrder(TreeNode node) { if (node == null) { return; } inOrder(node.left); // 遍历左子树 System.out.print(node.val + " "); // 访问当前节点 inOrder(node.right); // 遍历右子树 } // 后序遍历 public void postOrder(TreeNode node) { if (node == null) { return; } postOrder(node.left); // 遍历左子树 postOrder(node.right); // 遍历右子树 System.out.print(node.val + " "); // 访问当前节点 } } ``` 上述代码展示了如何通过递归实现二叉树的三种遍历方式。对于每一个节点,递归调用其左右子树并按指定顺打印节点值[^2]。 #### 三、非递归实现 除了递归之外,还可以利用栈结构来完成这些遍历操作。下面是非递归版本的具体实现: ##### 1. 前序遍历(非递归) ```java import java.util.Stack; public void iterativePreOrder(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); TreeNode current = root; while (current != null || !stack.isEmpty()) { if (current != null) { System.out.print(current.val + " "); stack.push(current); current = current.left; } else { current = stack.pop(); current = current.right; } } } ``` ##### 2. 中遍历(非递归) ```java import java.util.Stack; public void iterativeInOrder(TreeNode root) { Stack<TreeNode> stack = new Stack<>(); TreeNode current = root; while (current != null || !stack.isEmpty()) { if (current != null) { stack.push(current); current = current.left; } else { current = stack.pop(); System.out.print(current.val + " "); current = current.right; } } } ``` ##### 3. 后序遍历(非递归后序遍历稍微复杂一些,通常需要借助两个栈或者标记已经访问过的节点: ```java import java.util.Stack; public void iterativePostOrder(TreeNode root) { if (root == null) return; Stack<TreeNode> s1 = new Stack<>(); Stack<TreeNode> s2 = new Stack<>(); s1.push(root); while (!s1.isEmpty()) { TreeNode temp = s1.pop(); s2.push(temp); if (temp.left != null) { s1.push(temp.left); } if (temp.right != null) { s1.push(temp.right); } } while (!s2.isEmpty()) { System.out.print(s2.pop().val + " "); } } ``` 以上实现了不依赖于递归的堆栈机制来进行各种类型的遍历[^3]。 --- ### 总结 无论是采用递归还是迭代形式,都可以有效地完成二叉树的不同遍历需求。具体选择取决于实际应用场景个人偏好。如果追求简洁明了,则推荐使用递归;而当考虑性能优化或避免深层数组溢出风险时,可以尝试非递归方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值