JZ8 二叉树的下一个结点

这篇博客介绍了如何在带有父节点指针的二叉树中找到给定节点的中序遍历下一个节点。方法一是通过中序遍历找到目标值并返回其后继节点,方法二是根据节点的右子树和父节点关系直接定位。这两种方法的时间复杂度都是O(n),但方法二的代码更简洁。
摘要由CSDN通过智能技术生成

(题目见书或者网络原题)

给定一个二叉树其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的next指针。下图为一棵有9个节点的二叉树。树中从父节点指向子节点的指针用实线表示,从子节点指向父节点的用虚线表示

示例:

输入:{8,6,10,5,7,9,11},8

返回:9

解析:这个组装传入的子树根节点,其实就是整颗树,中序遍历{5,6,7,8,9,10,11},根节点8的下一个节点就是9,应该返回{9,10,11},后台只打印子树的下一个节点,所以只会打印9,如下图,其实都有指向左右孩子的指针,还有指向父节点的指针,下图没有画出来

方法一:

static int count_1 = 0;
static struct TreeLinkNode* ret = NULL;
void inOrder(struct TreeLinkNode* root, int val){
    if(root == NULL){
        return;
    }
    inOrder(root->left, val);
    if(count_1){
        ret = root;
        count_1 = 0;
        return;
    }

    if(root->val == val){
        count_1 = 1;
    }
    inOrder(root->right, val);
    
}
struct TreeLinkNode* GetNext(struct TreeLinkNode* pNode ) {
    struct TreeLinkNode* root = pNode;
    while(root -> next != NULL){
        root = root -> next;
    }
    inOrder(root, pNode->val);
    return ret;
}

方法一是自己写的,思路是简单的找到二叉树的root节点,然后进行正常的中序遍历,找到这个值返回对应节点,找不到则返回NULL。思路简单便于理解,相比来说,时间复杂度也是o(n)级别,但是比下面方法要长一些。

方法二:

struct TreeLinkNode* GetNext(struct TreeLinkNode* pNode ) {
    struct TreeLinkNode* root = pNode;
    if(root->right != NULL){
        root = root->right;
        while(root->left){
            root = root->left;
        }
        return root;
    }else if(root->next != NULL){
        if(root->next->left != NULL && root->next->left == root){
            return root->next;
        }else{
            while(root->next != NULL){
                if(root->next->left != NULL && root->next->left == root){
                    return root->next;
                }
                root = root->next;
            }
        }
    }
    return NULL;
}

方法二是对于中序遍历进行细致分析

情况一:如果有右子支,那么右子支的最左节点就是需要返回的节点。

情况二:如果没有右子支,则需要寻找父节点。父节点为右父节点,则返回该父节点。

情况三:如果父节点为左父节点,则寻找第一个右父节点,找到则返回该父节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值