Skip to content
本页目录

0144-二叉树的前序遍历

https://leetcode.cn/problems/binary-tree-preorder-traversal

给你二叉树的根节点 root ,返回它节点值的前序遍历。

示例 1:

输入:root = [1,null,2,3]
输出:[1,2,3]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

示例 4:

输入:root = [1,2]
输出:[1,2]

示例 5:

输入:root = [1,null,2]
输出:[1,2]

提示:

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100

进阶:递归算法很简单,你可以通过迭代算法完成吗?

思路 : 递归

前序遍历 : 根左右,递归调用

参考代码

csharp
public class Solution {
	List<int> list = new List<int>();

	private void dfs(TreeNode root){
		if(root == null){
			return;
		}
		list.Add(root.val);
		dfs(root.left);
		dfs(root.right);
	}

    public IList<int> PreorderTraversal(TreeNode root) {
    	dfs(root);
    	return list;
    }
}

思路2:迭代【官方】

递归调用的时候,隐式的维护了一个栈。
使用迭代的时候,我们需要将这个栈显示的申明出来。

迭代法模板

csharp
public class Solution {
	public IList<int> PreorderTraversal(TreeNode root) {
    	List<int> list = new List<int>();
    	Stack<TreeNode> stack = new Stack<TreeNode>();
    	TreeNode node = root;
    	while(stack.Count > 0 || node != null){
    		//遍历左节点
    		while(node != null){
    			// 前序:这里处理
    			// list.Add(node.val)
    			stack.Push(node);
    			node = node.left;
    		}
    		
    		//遍历根节点
    		node = stack.Pop();
    		//中序这里处理
    		//list.Add(node.val);

    		//遍历右节点
    		node = node.right;
    		//后续这里处理
    		// if(node.right == null){
    		// 	list.Add(node.val);	
    		// }
    	}
    	return list;
    }
}

参考代码

csharp
public class Solution {
	public IList<int> PreorderTraversal(TreeNode root) {
    	List<int> list = new List<int>();
    	Stack<TreeNode> stack = new Stack<TreeNode>();
    	TreeNode node = root;
    	while(stack.Count > 0 || node != null){
    		while(node != null){
    			list.Add(node.val);
    			stack.Push(node);
    			node = node.left;
    		}
    		node = stack.Pop();
    		node = node.right;
    	}
    	return list;
    }
}

思路3:Morris算法【官方】

Morris 遍历的核心思想是利用树的大量空闲指针,前序遍历规则如下

  1. 新建临时节点,令该节点为 root
  2. 如果当前节点的左子节点为空,将当前节点加入答案,并遍历当前节点的右子节点
  3. 如果当前节点的左子节点不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱结点
    • 如果前屈节点的右子节点为空,将前驱节点的右子节点设置为当前节点。 然后将当前节点加入答案,并将前驱节点的右子节点更新为当前节点。 当前节点更新为当前节点的左子节点 3.1 --> 如果前驱节点的右子节点为空,将前驱节点的右子节点设置为当前节点。然后将当前节点加入答案,并将当前节点更新为当前节点的左子节点。
    • 如果前屈节点的右子节点为当前节点,将它的右子节点重新设为空。当前节点更新为当前节点的右子节点。
  4. 重复步骤2和步骤3,只到遍历结束

Released under the MIT License.