面试题8:二叉树的下一个节点

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

解题思路

  有4种情况:

  • 该节点有右子树
  • 该节点没有右子树,且是根节点
  • 如果该节点没有右子树,且是左子节点
  • 该节点没有右子树,且是右子节点

上代码(C++香)

struct TreeLinkNode {
    int val;
    struct TreeLinkNode *left;
    struct TreeLinkNode *right;
    struct TreeLinkNode *next;
    TreeLinkNode(int x) :val(x), left(nullptr), right(nullptr), next(nullptr) {}
};

//            8
//        6      10
//       5 7    9  11
TreeLinkNode* GetNext(TreeLinkNode* pNode){
    if(pNode == nullptr)
        return nullptr;

    TreeLinkNode* pReturn = nullptr;
    // 1、如果该节点有右子树
    if(pNode->right != nullptr){
        pReturn = pNode->right;
        while(pReturn->left != nullptr)
            pReturn = pReturn->left;
        return pReturn;
    }
	// 2、如果该节点没有右子树,且是根节点
    else if(pNode->right == nullptr && pNode->next == nullptr){
        return nullptr;
    }
    // 3、如果该节点没有右子树,且是左子节点
    else if(pNode->right == nullptr && pNode->next->left == pNode){
        TreeLinkNode* pFather = pNode->next;
        return pFather;
    }
    // 4、如果该节点没有右子树,且是右子节点
    else if(pNode->right == nullptr && pNode->next->right == pNode){
        // 父节点,是爷节点的左子节点,如果一直是右子节点,那么就没有下一个节点,是nullptr
        TreeLinkNode* pFather = pNode->next;
        while(pFather->next != nullptr){
            if(pFather->next->right == pFather)
                pFather = pFather->next;
            else
                return pFather->next;
        }
        return nullptr;
    }
}