剑指offer:二叉树的下一个结点

来源:互联网 发布:java final 局部变量 编辑:程序博客网 时间:2024/05/01 12:45

题目描述

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针
解题思路:
1、要求一个节点(比如说用node表示)的中序遍历的下一个节点,首先判断这个节点是否有右子树,如果有右子树,那么他的下一个节点就是他右子树上最左边的节点,例如图1中b的下一个节点为e。
2、如果这个节点没有右孩子,就需要判断这个节点有没有父节点,如果没有父节点,那么中序遍历时,他的下一个节点就是空,比如说根节点。
3、如果有父节点,就要看这个节点是不是他的父节点的左孩子。如果是,那么中序遍历时,他的下一个结点就是他的父节点,比如说图1中节点d的下一个节点就是他的父节点b。
4、如果他不是他的父节点的左孩子,也就是他是他父节点的右孩子。那么就需要向树根方向寻找到一个节点N,这个结点要么是空(比如图2中c节点中序遍历中的下一个节点就是空,就是根节点a的父节点,这里要注意没有节点,有三个指针:分别指向左右孩子的指针,还有一个是指向父节点的指针),要么是使得节点node所在的子树是这个节点N的左孩子(如图1中节点e的中序遍历中下一个节点是a)。

using namespace std;
/*
struct TreeLinkNode {
    int val;
    struct TreeLinkNode *left;
    struct TreeLinkNode *right;
    struct TreeLinkNode *next;
    TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
        
    }
};
*/
class Solution {
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        if(NULL == pNode){
            return NULL;
        }
        if (pNode->right != NULL){
            return findLeft(pNode->right);
        }
        //如果结点的右子树为空
        else {
            //如果该结点没有父节点
            if (pNode->next == NULL){
                return NULL;
            }
            //如果该结点有父节点,他是父节点的左孩子
            if (pNode->next->left == pNode){
                return pNode->next;
            }
            //如果该结点有父节点,且他是父节点的右孩子
            else
                return findFatherNode(pNode->next);//寻找满足条件的父节点
        }
    }
    TreeLinkNode* findLeft(TreeLinkNode *pNode){
        if (pNode->left){
            pNode = pNode->left;
        }
        return pNode;
    }
    TreeLinkNode* findFatherNode(TreeLinkNode *pNode){
        while (pNode->next){
            if(pNode->next->left == pNode){
                return pNode->next;
            }
            pNode = pNode->next;
        }
        return NULL;
    }
};
0 0
原创粉丝点击