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

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

二分木が与えられたとき、次のプロパティ(性質)を満たしていれば、その二分木は有効とみなされます。

  • 各ノードのデータ値は、左の子ノードと右の子ノードの値の合計と一致していなければなりません。どちらかの側に子ノードが存在しない場合は、その値は0として扱われます。

例えば、以下のような木が与えられた場合、このプロパティを満たしていることになります。

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

この性質を確認するための特別なトリックは存在せず、木を再帰的に走査する必要があります。ノードとその両方の子がプロパティを満たしていればtrueを返し、そうでなければfalseを返します。

アルゴリズムの流れ

検証は以下の手順で行われます。

  1. ノードがNULL、または葉ノード(子を持たないノード)であれば、trueを返します。
  2. 左の子が存在すればその値を取得し、存在しなければ0とします。
  3. 右の子についても同様に処理します。
  4. 現在のノードの値が左右の子の値の合計と一致し、かつ左右の部分木も再帰的にプロパティを満たしていればtrueを返します。

実装例

#include <iostream>
using namespace std;
class node {
   public:
   int data;
   node* left;
   node* right;
};
bool isValidBinaryTree(node* nd) {
   int left_data = 0, right_data = 0;
   if(nd == NULL || (nd->left == NULL && nd->right == NULL))
      return 1;
   else{
      if(nd->left != NULL)
         left_data = nd->left->data;
      if(nd->right != NULL)
         right_data = nd->right->data;
      if((nd->data == left_data + right_data)&& isValidBinaryTree(nd->left) && isValidBinaryTree(nd->right))
         return true;
      else
         return false;
   }
}
node* getNode(int data) {
   node* newNode = new node();
   newNode->data = data;
   newNode->left = NULL;
   newNode->right = NULL;
   return newNode;
}
int main() {
   node *root = getNode(10);
   root->left = getNode(8);
   root->right = getNode(2);
   root->left->left = getNode(3);
   root->left->right = getNode(5);
   root->right->right = getNode(2);
   if(isValidBinaryTree(root))
      cout << "The tree satisfies the children sum property ";
   else
      cout << "The tree does not satisfy the children sum property ";
}

出力

The tree satisfies the children sum property

計算量について

このアルゴリズムの時間計算量はO(n)です(nは木のノード数)。すべてのノードを一度だけ訪問するため、効率的に検証できます。また、再帰呼び出しの深さは木の高さに依存するため、バランスの取れていない木ではスタック領域に注意が必要です。

  1. C++で二分木がSumTree(総和木)かどうかを判定する方法

    ここでは、与えられた二分木が「SumTree(総和木)」であるかどうかを判定する方法を解説します。まずは、SumTreeとはどのような木なのかを確認しておきましょう。 SumTreeとは SumTreeとは、すべての内部ノードが「左の子と右の子の値の合計」を保持する特殊な二分木です。木の根(ルート)には、それより下位に存在する全要素の合計値が格納されます。なお、葉ノードのみからなる木や空の木も、定義上はSumTreeとみなされます。以下はSumTreeの一例です。 例えば上図の木では、根の値26が左部分木(10 + 4 + 6 = 20)と右部分木(3 + 3 = 6)の合計と一致しており

  2. C++で二分木が別の二分木の部分木(サブツリー)であるかを判定する方法

    はじめに二つの二分木が与えられたとき、小さい方の木がもう一方の二分木の部分木(サブツリー)として含まれているかどうかを判定する方法を解説します。例として、以下のような二つの木を考えてみましょう。この場合、2番目の木は1番目の木の部分木となっています。判定アルゴリズムの考え方この性質を確認するためには、大きい方の木を後順走査(post-order traversal)でたどり、各ノードを根とする部分木が2番目の木と完全に一致するかどうかを順番に調べます。一致する部分木が一つでも見つかれば、2番目の木は1番目の木の部分木であると判定できます。判定の流れは以下の通りです。1. 部分木側がNULLであ