leetcode#144 二叉树的前序遍历

这篇博客详细介绍了如何实现二叉树的前序遍历,包括经典的递归和迭代方法,以及更高效的Morris遍历算法。通过示例代码解释了Morris遍历的工作原理,该方法巧妙地利用空指针减少额外空间的使用,实现了线性时间复杂度的前序遍历。
摘要由CSDN通过智能技术生成

leetcode#144 二叉树的前序遍历

题目:

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

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

思路:

递归。
迭代。

Morris遍历:

我们递归和迭代时,实际上用了一个栈去维护访问节点顺序,以便回溯。
我们可以这样,用空余指针指向回溯的下一个点,这样就不用存储序列了。
对于一个点,什么时候会回溯到当前点,显然,当我们遍历完左子树最后一个点时,会回到这个点,如果用栈,就把栈回退到当前点。然而我们可以用左子树的最后一个点的指针指向当前点,这样当遍历完成过后,根据指针可以直接回到当前点。
细节:
p1为当前点,p2为临时指针指向p2->left也就是左子树,用p2=p2->right的方式,一直遍历右子树,这样就可以得到p1的前驱节点,让前驱节点指向当前节点即可,代表左子树已经遍历完,这样当遍历到这个点时直接p1->right就能返回当前节点,返回当前节点后,再次遍历找前驱节点,前驱节点的下一个节点改为null即可。

代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution
{
public:
    vector<int> preorderTraversal(TreeNode *root)
    {
        vector<int> ans;
        if (!root)
            return ans;
        TreeNode *p1 = root, *p2 = NULL;
        while (p1)
        {
            p2 = p1->left;
            if (p2)
            {
                while (p2->right && p2->right!= p1)
                    p2 = p2->right;
                if (p2->right == NULL)
                {
                    ans.emplace_back(p1->val);
                    p2->right = p1;
                    p1 = p1->left;
                    continue;
                }
                else
                    p2->right = NULL;
            }
            else
                ans.emplace_back(p1->val);
            p1 = p1->right;
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值