C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で連続ツリー(Continuous Tree)を判定するアルゴリズムと実装例

連続ツリー(Continuous Tree)とは

連続ツリーとは、ルートノードから葉ノードまでのすべての経路において、親ノードとそのすべての直接の子ノードとの値(重み)の絶対差が常に1となるような木のことです。

ルートから葉への経路上の任意のノードを選んだとき、次の条件が必ず成り立ちます。

|ノードの値 − 左の子ノードの値| = 1(右の子ノードについても同様に成り立つ)

図解と具体例

具体例を見ながら理解を深めましょう。

下の木は、親ノードとその子ノードの値の絶対差が常に1であるため、連続ツリーとみなされます。

C++で連続ツリー(Continuous Tree)を判定するアルゴリズムと実装例

一方、下の木は親子ノード間の絶対差が1になっていない箇所があるため、連続ツリーの条件を満たしていません。

C++で連続ツリー(Continuous Tree)を判定するアルゴリズムと実装例

木が連続しているかを判定するアルゴリズム

判定は再帰的に行います。手順は以下のとおりです。

  • ルートがNULLの場合は1を返す(終了条件)。
  • 葉ノードに到達した場合は1を返す。その経路はここまで連続していたことを意味する。
  • 左の部分木が空の場合は、現在のノードと右の子の値の絶対差を計算して連続性を確認し、右の部分木に対して再帰的に処理を続ける。
  • 右の部分木が空の場合は、現在のノードと左の子の値の絶対差を計算して連続性を確認し、左の部分木に対して再帰的に処理を続ける。
  • どちらの子も存在する場合は、左右両方の子との絶対差を計算して連続性を確認し、左右の部分木に対して再帰的に処理を続ける。

擬似コード(C++実装)

// 木が連続しているかどうかを判定する関数
struct btreeNode{
    int data;
    btreeNode* left, * right;
};
int isContinuous(btreeNode *root){
    // ノードがNULLの場合は1を返す(終了条件)
    if (root == NULL)
        return 1;
    // 葉ノードに到達した場合、この経路はここまで連続しているはず
    if (root->left == NULL && root->right == NULL)
        return 1;
    // 左の子が存在しない場合
    if (root->left == NULL)
        return (abs(root->data - root->right->data) == 1) && isContinuous(root->right);
    // 右の子が存在しない場合
    if (root->right == NULL)
        return (abs(root->data - root->left->data) == 1) && isContinuous(root->left);
    // 左右両方の子との絶対差を計算
    return abs(root->data - root->left->data)==1 && abs(root->data - root->right->data)==1 &&
        isContinuous(root->left) && isContinuous(root->right);
}

計算量について

このアルゴリズムは木のすべてのノードを一度ずつ訪問するため、ノード数をnとすると時間計算量はO(n)となります。また、再帰呼び出しの深さは木の高さに依存するため、平衡な木であれば空間計算量はO(log n)、最悪ケース(線形リスト状の木)ではO(n)となります。


  1. C++で二分木の子ノード合計プロパティを検証する方法

    二分木が与えられたとき、次のプロパティ(性質)を満たしていれば、その二分木は有効とみなされます。各ノードのデータ値は、左の子ノードと右の子ノードの値の合計と一致していなければなりません。どちらかの側に子ノードが存在しない場合は、その値は0として扱われます。例えば、以下のような木が与えられた場合、このプロパティを満たしていることになります。この性質を確認するための特別なトリックは存在せず、木を再帰的に走査する必要があります。ノードとその両方の子がプロパティを満たしていればtrueを返し、そうでなければfalseを返します。アルゴリズムの流れ検証は以下の手順で行われます。ノードがNULL、または葉

  2. C++で実装する二分木の反時計回りスパイラル走査:アルゴリズムとサンプルコードを解説

    二分木の反時計回りスパイラル走査(Anti-Clockwise Spiral Traversal)とは、木のノードを渦巻き状に、かつ通常とは逆向きの順序でたどっていく走査方法です。根(トップのノード)から開始し、レベル(深さ)ごとに左右の方向を交互に切り替えながら、木の外側から内側へと渦を描くようにノードを出力していきます。 下図は、二分木を反時計回りにスパイラル走査した際の訪問順序を示したものです。 アルゴリズムの流れ 二分木をスパイラル走査するためのアルゴリズムは、次の手順で動作します。 2つの変数 i と j を用意し、i は最上位レベル「1」、j は木の高さでそれぞれ初期化します。