LeetCode_144 二叉树的前序遍历

本文详细介绍了二叉树前序遍历的三种方法:递归、迭代和Morris遍历。递归方法遵循根-左-右的顺序;迭代方法使用栈来模拟递归过程;Morris遍历则通过改变树结构进行遍历。每种方法都有其独特之处,适用于不同的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、题目:二叉树的前序遍历

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

2、解题思路

方法一:递归

        前序遍历的流程是,根节点->左子树->右子树,如果左子树也作为根,那么也重复一遍根节点->左子树->右子树,所以这个过程天生就具有递归的性质,所以我们可以在递归时,先递归自己的左子树,然后再递归自己的右子树,递归终止的条件是碰到空指针。

方法二:迭代

        我们也可以用迭代的方式实现方法一的递归函数,两种方式是等价的,区别在于递归的时候隐式地维护了一个栈,而我们在迭代的时候需要显式地将这个栈模拟出来,其余的实现与细节都相同。

方法三:Morris 遍历

        Morris遍历的个人小见解_W__winter的博客-优快云博客

3、代码

//递归
class Solution 
{
public:
	void preorder(TreeNode* root, vector<int>& res) 
	{
		if (root == nullptr) 
		{
			return;
		}
		res.push_back(root->val);
        //先去找递归左子树,等左子树递归完毕之后就开始递归右子树
		preorder(root->left, res);
		preorder(root->right, res);
	}

	vector<int> preorderTraversal(TreeNode* root) 
	{
		vector<int> res;
		preorder(root, res);
		return res;
	}
};
class Solution 
{
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        st.push(root);
        while (!st.empty()) 
        {
            TreeNode* node = st.top();                       // 中
            st.pop();
            result.push_back(node->val);
            if (node->right) st.push(node->right);           // 右(空节点不入栈)
            if (node->left) st.push(node->left);             // 左(空节点不入栈)
        }
        return result;
    }
};
//迭代
class Solution 
{
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        vector<int> res;
        if (root == nullptr) 
        {
            return res;
        }

        stack<TreeNode*> stk;
        TreeNode* node = root;
        while (!stk.empty() || node != nullptr) 
        {
            //这个while的意思是一直往左边的树找下去,找到最深的地方
            //可以将stack理解成存入的都是根节点,如果不是根节点就会直接被pop掉
            //这里的根指的是每个小三角的根
            while (node != nullptr) 
            {
                res.emplace_back(node->val);
                stk.emplace(node);
                node = node->left;
            }
            //运行到这里说明左子树已经遍历完了,开始遍历右子树的
            //这里的子树指的也都是小三角的子树
            node = stk.top();
            stk.pop();
            node = node->right;
        }
        return res;
    }
};
//Morris遍历
public:
    vector<int> preorderTraversal(TreeNode* root) 
    {
        vector<int> res;
        if (root == nullptr) 
        {
            return res;
        }

        TreeNode* p1 = root, * p2 = nullptr;

        while (p1 != nullptr) 
        {
            p2 = p1->left;
            if (p2 != nullptr) 
            {
                while (p2->right != nullptr && p2->right != p1) 
                {
                    p2 = p2->right;
                }
                 
                if (p2->right == nullptr) 
                {
                    res.emplace_back(p1->val);
                    p2->right = p1;
                    p1 = p1->left;
                    continue;
                }
                else 
                {
                    p2->right = nullptr;
                }
            }
            else 
            {
                res.emplace_back(p1->val);
            }
            p1 = p1->right;
        }
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值