面试理想汽车,给我整蒙了。。。

文章讨论了一位网友在理想汽车面试时关于二叉树后序遍历的理解争议,网友认为是左->右->根,而面试官持不同意见。文章解释了后序遍历的基本规则,并提供了C++、C和Python的后序遍历代码示例。
摘要由CSDN通过智能技术生成

最近在网上看到一帖子,一网友在理想汽车面试的时候,聊到二叉树的后序遍历,该网友说是:左->右->中,但面试官坚持说不是,把他给整蒙了。

7f5bc3724915bc1311b938a4bcf66d22.png

我们这里来回顾一下二叉树的遍历方式,我们听过最多的就是前序遍历,中序遍历和后序遍历,其实这三种遍历方式都是根据根节点的位置来判断的。先遍历根节点就是先序遍历,最后遍历根节点就是后续遍历,如果根节点放在左右子节点中间就是中序遍历,如下所示:

前序遍历根节点->左子树->右子树

中序遍历:左子树->根节点->右子树

后序遍历:左子树->右子树->根节点

这三种遍历方式无论是哪种,都是左子树在右子树之前遍历。我们再来看下该网友的回复,他说的是左->右->中,这个中应该就是根节点,所以他说的是没问题的,但面试官坚持说不是,可以肯定一点的是这个面试官要么是水平有问题要么是故意找茬。

我们来看下其他网友的回复,一网友调侃说:你和面试官面对面,你俩左右是相反的。

694c262d282164501d8244ca75eaceef.png

还有的说面试官大脑内存可能存在的是左右根,你说的和他大脑内存存储的不匹配。

3bf129cab8f70890df4d6eae38af7449.png

还有的说理想汽车和我争了两个问题,全是错的,又菜又犟。

a69efa119cda8b2e70ecffa6f8f2bdf3.png

其实这种情况我也遇到过类似的,至少遇到两次,明明我说的是对,面试官非说不对,但当时并没有给我整蒙,因为我知道我说的是对的,只是感到挺无语的,怎么会有这么二百五的面试官。

我之前也面试过很多人,如果真的遇到我的知识盲区的话,我绝对不会说一个错误的答案。知道就是知道,不知道就是不知道。明明自己是错的,非说自己是对的,不知道这种人是什么心态。

我们来看一下二叉树的后序遍历,写法也比较多,有递归的还有非递归的,具体可以看下《算法秘籍》的第4章。当然还有一种比较经典的写法就是 Morris遍历,我们前面也讲过,大家可以看下:Morris的后序遍历,这里就不在重复介绍。因为当时只提供了java语言的代码,这里再来提供其他语言的代码。

C++:

public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> posList;
        TreeNode *cur = root;// 记录当前访问的节点。
        while (cur) {
            if (cur->left == nullptr) {// 左子节点为空不用管。
                cur = cur->right;
            } else {
                TreeNode *pre = cur->left;
                while (pre->right && pre->right != cur)
                    pre = pre->right;
                if (pre->right == nullptr) {// 第一次到当前节点。
                    pre->right = cur;
                    cur = cur->left;
                } else {// 第二次到当前节点。
                    pre->right = nullptr;
                    // 1,当前节点第二次访问的时候逆序打印。
                    printList(cur->left, posList);
                    cur = cur->right;
                }
            }
        }
        // 2,根节点往右的逆序要单独打印。
        printList(root, posList);
        return posList;
    }

    // 逆序打印
    void printList(TreeNode *node, vector<int> &posList) {
        int count = 0;
        while (node) {
            ++count;
            posList.emplace_back(node->val);
            node = node->right;
        }
        // 反转
        reverse(posList.end() - count, posList.end());
    }

C:

// 逆序打印
void printList(struct TreeNode *node, int *res, int *returnSize) {
    int count = 0;
    while (node) {
        ++count;
        res[(*returnSize)++] = node->val;
        node = node->right;
    }
    // 反转
    for (int i = (*returnSize) - count, j = (*returnSize) - 1; i < j; i++, j--) {
        int tmp = res[i];
        res[i] = res[j];
        res[j] = tmp;
    }
}

int *postorderTraversal(struct TreeNode *root, int *returnSize) {
    *returnSize = 0;
    // 题中树的节点的数目在范围 [0, 100] 内
    int *res = malloc(sizeof(int) * 201);
    struct TreeNode *cur = root;// 记录当前访问的节点。
    while (cur) {
        if (cur->left == NULL) {// 左子节点为空不用管。
            cur = cur->right;
        } else {
            struct TreeNode *pre = cur->left;
            while (pre->right && pre->right != cur)
                pre = pre->right;
            if (pre->right == NULL) {// 第一次到当前节点。
                pre->right = cur;
                cur = cur->left;
            } else {// 第二次到当前节点。
                pre->right = NULL;
                // 1,当前节点第二次访问的时候逆序打印。
                printList(cur->left, res, returnSize);
                cur = cur->right;
            }
        }
    }
    // 2,根节点往右的逆序要单独打印。
    printList(root, res, returnSize);
    return res;
}

Python:

def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
    posList = []
    cur = root  # 记录当前访问的节点。
    while cur:
        if not cur.left:  # 左子节点为空不用管。
            cur = cur.right
        else:
            pre = cur.left
            while pre.right and pre.right != cur:
                pre = pre.right
            if not pre.right:  # 第一次到当前节点。
                pre.right = cur
                cur = cur.left
            else:  # 第二次到当前节点。
                pre.right = None
                # 1,当前节点第二次访问的时候逆序打印。
                self.printList(cur.left, posList)
                cur = cur.right
    # 2,根节点往右的逆序要单独打印。
    self.printList(root, posList)
    return posList

# 逆序打印
def printList(self, node, posList):
    count = 0
    while node:
        count += 1
        posList.append(node.val)
        node = node.right
    # 反转
    length = len(posList)
    posList[length - count:length] = posList[length - count:length][::-1]

99d6d510b6d09eee36b0cc113e053eb1.gif

笔者简介

博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解700多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值