面试题 04.06. 后继者

本文详细介绍了如何在二叉搜索树中找到指定节点的中序后继,即“下一个”节点。算法分为两种情况:一是当指定节点有右孩子时,从右孩子开始找到右子树的最小节点;二是当指定节点没有右孩子时,从根节点开始遍历,找到第一个大于指定节点的节点。代码实现中使用了递归的方法,时间复杂度和空间复杂度均为O(1)。
摘要由CSDN通过智能技术生成

难度:中等

目录

一、问题描述

二、思路

1、解题思路

三、解题

1、代码实现

2、时间复杂度 and 空间复杂度


一、问题描述

这里直接采用LeetCode上面的问题描述。

设计一个算法,找出二叉搜索树中指定节点的“下一个”节点(也即中序后继)。

如果指定节点没有对应的“下一个”节点,则返回null

下面给出示例:

二、思路

1、解题思路

        可以将该题看成在二叉搜索树中,寻找只大于指定节点的 一个节点,因为该树是二叉搜索树,所以具有以下特征:

  1. 若左子树不为空,则左子树上所有的节点都小于根节点。
  2. 若右子树不为空,则右子树上所有的节点都小于根节点。
  3. 左右子树也为二叉搜索树。

这里我们的目标节点为 p:分下面两种情况讨论

        情况一:p节点存在右孩子:假设p节点 == 5,那么需要从p节点的右子树中找到一个只大于p节点的节点。那么需要判断p节点的右节点是否为NULL,如果是NULL那么直接返回NULL即可。如果p节点的右孩子节点不为空,则要搜索p节点的右孩子直至为叶子节点为止。即为刚好大于p节点的节点。

        情况二:p节点不存在右孩子:那么需要从根节点开始搜索,保存一个大于p节点的节点为 ans ,每次向下搜索如果该节点大于p节点都更新为ans,直至搜索至p节点,那么保存的节点 ans一定为刚好大于 p节点的节点。假设p节点 == 2 ,刚开始更新 ans == 5,5 > 2 往左子树进行搜索;3 > 2 ,再更新 ans == 3,往左子树搜索; 1 < 2 往右子树搜索 2 == 2。此时直接返回 ans ==3 即可。

 

三、解题

1、代码实现

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* inorderSuccessor(struct TreeNode* root, struct TreeNode* p) {
    struct TreeNode *ans = NULL;
    //往p节点的右子树搜索,找到p节点右子树最小的节点返回即为节点p的下一个节点
    if (p->right != NULL) {
        ans = p->right;
        while (ans->left) {
            ans = ans->left;
        }
        return ans;
    }
    //循环结束后保留左子树中刚好大于 p节点的节点 为 ans
    while (root) {
        if (root->val > p->val) {
            ans = root;
            root = root->left;
        } else {
            root = root->right;
        }
    }
    return ans;
}

 

2、时间复杂度 and 空间复杂度

时间复杂度:O(n log(n)))

空间复杂度:O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_Alkaid_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值