剣はオファーを指します(C ++)-JZ8:バイナリツリーの次のノード(データ構造-ツリー)

著者:Steven Zhai
著作権表示:著作権は著者に帰属します。商用の再版については、承認を得るために著者に連絡してください。非商用の再版については、出典を示してください。

トピックの説明:

二分木のノードが与えられた場合、次のノードを逆順で見つけて戻ります。ツリー内のノードには、左右の子ノードだけでなく、親ノードへの次のポインタも含まれていることに注意してください。次の図は、9ノードの二分木を示しています。ツリー内の親ノードから子ノードへのポインターは実線で表され、子ノードから親ノードへのポインターは破線で表されます。

例:

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

返品:9

分析:このアセンブリによって渡されるサブツリーのルートノードは、実際にはツリー全体です。順番にトラバーサル{5,6,7,8,9,10,11}、ルートノード8の次のノードは9です。これは{9,10,11}を返すはずですが、背景はサブツリーの次のノードのみを印刷するため、下の図に示すように9のみが印刷されます。実際、左右の子へのポインターもあります。下の図には描かれていない親ノードへのポインタとして

データ範囲:ノードの数は1≤n≤50を満たし、ノードの値は1≤val≤100の 

要件を満たします:空間の複雑さO(1)、時間の複雑さO(n) 

例:

入力:

{8,6,10,5,7,9,11}、8

戻り値:

9

問題解決のアイデア:

この質問では、データ構造ツリーの使用について調べます。2つの方法:

1)ブルートフォースクラッキング。次のポインタを介してルートノードを取得し、途中で並べ替え、並べ替えプロセス中にベクトルに格納してから、位置に従って直接出力します。

2)順序どおりの並べ替えのプロパティと組み合わせる。ノードに右のサブツリーがある場合、右のサブツリーの左端の子が次のノードになります。右のサブツリーがない場合、最初の右の親が次のノードになります。

テストコード:

1)ブルートフォースクラッキング。

/*
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(!pNode)
            return NULL;
        // 确定根结点
        TreeLinkNode* root=pNode;
        while(root->next)
        {
            root=root->next;
        }
        // 中序排序
        vector<TreeLinkNode*> v;
        inorder(root,v);
        for(int i=0;i<v.size();++i)
        {
            if(v[i]==pNode&&(i+1)<v.size())
                return v[i+1];
        }
        return NULL;
    }
    
    // 排序
    void inorder(TreeLinkNode* root,vector<TreeLinkNode*> &v)
    {
        if(!root)
            return;
        // 中序排序
        inorder(root->left,v);
        v.push_back(root);
        inorder(root->right,v);
    }
};

2)順序どおりの並べ替えのプロパティと組み合わせる。

/*
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(!pNode)
            return NULL;
        // 判断是否存在右子树
        if(pNode->right)
        {
            TreeLinkNode* target=pNode->right;
            // 取最左孩子
            while(target->left)
            {
                target=target->left;
            }
            return target;
        }
        // 不存在右子树,寻找第一个右父亲
        while(pNode->next)
        {
            if(pNode->next->left==pNode)
                return pNode->next;
            pNode=pNode->next;
        }
        return NULL;
    }
    

};

おすすめ

転載: blog.csdn.net/zhaitianbao/article/details/123876984
おすすめ