Java实现 LeetCode 589.N叉树的前序遍历+590.N叉树的后序遍历+429.N叉树的层序遍历

本文深入探讨了N叉树的前序、后序及层序遍历算法,包括递归与迭代两种实现方式,提供了详细的代码示例,帮助读者理解并掌握N叉树遍历的原理与实践。

589.N叉树的前序遍历
给定一个 N 叉树,返回其节点值的前序遍历。

例如,给定一个 3叉树 :
在这里插入图片描述

返回其前序遍历: [1,3,5,6,2,4]。

说明: 递归法很简单,你可以使用迭代法完成此题吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  1. 递归
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<Integer> preorder(Node root) {
        List<Integer> ans = new ArrayList<Integer>();
		if(root == null) return ans;
        ans.add(root.val);
		preOrder(ans,root.children);
		return ans;
    }
	private void preOrder(List<Integer> ans, List<Node> children) {
		if(children.isEmpty()) return;
		for(Node node : children) {
			ans.add(node.val);
			preOrder(ans, node.children);
		}
    }
}
  1. 迭代
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<Integer> preorder(Node root) {
       List<Integer> ans = new ArrayList<Integer>();
        if(root == null) return ans;
        LinkedList<Node> stack = new LinkedList<>();
       stack.add(root);
       while(!stack.isEmpty()) {
    	   Node node = stack.pollLast();
    	   ans.add(node.val);
    	   Collections.reverse(node.children);
    	   for(Node t : node.children) {
    		   stack.add(t);
    	   }
       }
       return ans;
    }
}

590.N叉树的后序遍历
给定一个 N 叉树,返回其节点值的后序遍历。

例如,给定一个 3叉树 :
在这里插入图片描述

返回其后序遍历: [5,6,3,2,4,1].

说明: 递归法很简单,你可以使用迭代法完成此题吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  1. 递归
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<Integer> postorder(Node root) {
       List<Integer> ans = new ArrayList<Integer>();
	    if(root == null) return ans;
	    Node node = root;
	    postOrder(ans,root.children);
	    ans.add(node.val);
	    return ans;
	}
	private void postOrder(List<Integer> ans, List<Node> children) {
		if(children.isEmpty()) {
			return;
		}
		for(Node node : children) {
			postOrder(ans,node.children);
			ans.add(node.val);
		}
	
    }
}
  1. 迭代
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<Integer> postorder(Node root) {
        List<Integer> ans = new ArrayList<Integer>();
		if(root == null) return ans;
		Stack<Node> stack = new Stack<>();
		stack.add(root);
		//ans.add(root.val);
		while(!stack.isEmpty()) {
			Node node = stack.pop();
			ans.add(node.val);
			for(Node n : node.children) {
				stack.add(n);
			}
		}
		Collections.reverse(ans);
		return ans;
    }
}

429.N叉树的层序遍历
给定一个 N 叉树,返回其节点值的层序遍历。 (即从左到右,逐层遍历)。

例如,给定一个 3叉树 :

在这里插入图片描述

返回其层序遍历:

[
[1],
[3,2,4],
[5,6]
]

说明:

树的深度不会超过 1000。
树的节点总数不会超过 5000。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
       List<List<Integer>> ans = new ArrayList<List<Integer>>();
        if(root == null) return ans;
        Queue<Node> queue = new LinkedList<>();
        queue.add(root);
        while(!queue.isEmpty()) {
        	List<Integer> list = new ArrayList<>();
        	int size = queue.size();
        	for(int i = 0; i < size; i++) {
        		Node node = queue.poll();
        		list.add(node.val);
        		for(Node n : node.children) {
        			queue.add(n);
        		}
        	}
        	ans.add(list);
        }
        return ans;
    }
}
<think>嗯,用户想了解如何用代码实现叉树前序、中序、后序遍历算法,还提到了示例。首先,我得回忆一下这三种遍历的基本概念和它们的顺序区别。前序遍历是根-左-右,中序是左-根-右,后序是左-右-根。对吧? 接下来,用户可能需要具体的代码示例,所以得考虑用哪种编程语言。根据提供的引用,特别是引用3,里面提到了C++的递归实现,但用户可能对Python更熟悉,或者需要多种语言的例子?不过用户的问题里没有特别说明,可能默认是常见的语言,比如Python或者Java。不过原问题中的示例代码是Python的快速排序,所以可能用户更倾向于Python。不过引用3是C++,需要确认。不过用户的问题里直接问的是如何用代码实现,所以可能需要提供多种方法,比如递归和迭代,以及不同语言的示例? 然后,根据引用3,递归算法相对简单,结构清晰。比如前序遍历递归就是先访问根节点,然后递归左子树,再递归右子树。同样,中序和后序调整访问顺序即可。但是用户可能需要递归和迭代两种方法,因为有时候迭代更高效,或者避免栈溢出的问题。引用3中的示例是递归的,但LeetCode也常要求迭代解法。所以可能需要同时给出递归和迭代的实现。 另外,引用1和4提到根据前序和中序重建二叉树,这可能和遍历有关联,但用户的问题主要是遍历实现,而不是重建。不过可能需要简单提及遍历的应用,比如重建二叉树需要中序加前序后序,但用户的问题集中在遍历实现方法。 现在,结构上可能需要分递归和迭代两部分,分别说明前序、中序、后序实现。对于递归,代码相对简单,调整访问顺序即可。对于迭代,可能需要使用栈,处理顺序不同。例如,前序的迭代可以用栈,先压入根,然后循环弹出,访问后先压右再压左。中序迭代则用栈和指针,先走到最左,再处理节点,再转向右子树。后序迭代相对复杂,可能需要两个栈,或者逆序处理。 另外,用户可能需要代码示例的注释,解释每一步的作用。比如递归的终止条件,迭代中的栈操作等。还要注意代码的正确性,比如在Python中如何定义树的结构,可能需要先定义TreeNode类。但用户的问题可能更关注遍历算法本身,而不是树的结构定义,所以示例代码中可能需要包含一个简单的树结构定义。 例如,在Python中,可以定义一个TreeNode类,包含val、left、right属性。然后编写前序、中序、后序的递归和迭代函数。比如递归前序就是先append根的值,然后递归左,递归右。中序则是先递归左,append根,再递归右。后序递归左、右,最后append根。 对于迭代的实现前序可以用栈,每次弹出节点,访问后先压右子节点,再压左子节点。中序迭代需要维护当前节点指针,先走到最左,然后弹出栈顶,访问后处理右子树。后序迭代可以用一个栈,类似前序,但顺序调整为根-右-左,然后反转结果得到左-右-根的顺序。或者用两个栈,第二个栈用来反转顺序。 此外,层序遍历可能不属于用户的问题范围,但引用3提到了层序遍历,但用户的问题明确前、中、后序,所以可能不需要涉及层序。 还需要注意代码的语法正确性,比如Python中的缩进,函数定义等。比如在递归函数中,可能需要将结果保存在一个列表中,可以通过传递列表作为参数,或者使用类的成员变量,或者使用嵌套函数。例如,在Python中,可以在函数内部定义递归辅助函数,或者通过修改外部列表。 比如,递归的前序遍历函数可以这样写: def preorderTraversal(root): res = [] def helper(node): if not node: return res.append(node.val) helper(node.left) helper(node.right) helper(root) return res 类似地,中序和后序调整append的位置即可。 对于迭代版本,前序的Python代码可能如下: def preorder_iterative(root): res = [] stack = [root] while stack: node = stack.pop() if node: res.append(node.val) stack.append(node.right) stack.append(node.left) return res 需要注意的是,栈中可能压入None节点,所以在弹出后需要判断是否为空。或者可以调整条件,只压入非空节点,但初始时可能root为空的情况需要处理。 中序迭代: def inorder_iterative(root): res = [] stack = [] curr = root while curr or stack: while curr: stack.append(curr) curr = curr.left curr = stack.pop() res.append(curr.val) curr = curr.right return res 后序迭代的一种方法: def postorder_iterative(root): res = [] stack = [root] while stack: node = stack.pop() if node: res.append(node.val) stack.append(node.left) stack.append(node.right) return res[::-1] 这里先将根压栈,然后按根-右-左的顺序处理,最后反转结果得到后序的左-右-根。 这样,用户可以得到递归和迭代的代码示例,并了解不同遍历实现方式。 另外,用户可能想知道时间复杂度和空间复杂度。三种遍历的时间都是O(n),空间复杂度递归是O(h)(h为树的高度,栈空间),迭代法也是O(n),因为栈的大小最坏情况是O(n)(比如退化为链表)。 最后,根据用户提供的引用,特别是引用2提到后序遍历适用于表达式树,可能可以补充应用场景,但用户的问题集中在代码实现,所以可能不需要展开,但可以简要提及。 在总结时,需要确保代码示例正确,符合语法,并且解释清晰。可能需要检查每个遍历的步骤是否正确,例如迭代后序实现是否确实通过反转前序的变体得到正确结果。</think>### 二叉树前序、中序、后序遍历实现方法 二叉树遍历是基础算法问题,以下是递归和迭代两种实现方式,以Python为例(假设已定义`TreeNode`类,包含`val`、`left`、`right`属性)。 --- ### 1. 递归实现 递归方法通过调整节点访问顺序实现不同遍历方式。 #### **前序遍历**(根→左→右) ```python def preorder_recursive(root): res = [] def helper(node): if not node: return res.append(node.val) # 先访问根节点 helper(node.left) helper(node.right) helper(root) return res ``` #### **中序遍历**(左→根→右) ```python def inorder_recursive(root): res = [] def helper(node): if not node: return helper(node.left) res.append(node.val) # 中间访问根节点 helper(node.right) helper(root) return res ``` #### **后序遍历**(左→右→根) ```python def postorder_recursive(root): res = [] def helper(node): if not node: return helper(node.left) helper(node.right) res.append(node.val) # 最后访问根节点 helper(root) return res ``` --- ### 2. 迭代实现 迭代方法通过栈模拟递归过程,控制节点访问顺序。 #### **前序遍历** ```python def preorder_iterative(root): res = [] stack = [root] while stack: node = stack.pop() if node: res.append(node.val) stack.append(node.right) # 先压右节点(后弹出) stack.append(node.left) # 后压左节点(先弹出) return res ``` #### **中序遍历** ```python def inorder_iterative(root): res = [] stack = [] curr = root while curr or stack: while curr: # 走到最左子节点 stack.append(curr) curr = curr.left curr = stack.pop() res.append(curr.val) curr = curr.right # 转向右子树 return res ``` #### **后序遍历** ```python def postorder_iterative(root): res = [] stack = [root] while stack: node = stack.pop() if node: res.append(node.val) stack.append(node.left) # 先压左节点(后弹出) stack.append(node.right) # 后压右节点(先弹出) return res[::-1] # 反转根→右→左→结果为左→右→根 ``` --- ### 关键点说明 1. **时间复杂度**:所有方法均为$O(n)$,每个节点访问一次。 2. **空间复杂度**: - 递归方法:$O(h)$($h$为树的高度,递归栈深度)。 - 迭代方法:$O(n)$(最坏情况下栈空间占用)。 3. **应用场景**: - 前序遍历:复制二叉树结构或序列化[^2]。 - 中序遍历:二叉搜索树的有序输出。 - 后序遍历:表达式树的后缀计算[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值