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

C++で二分木の各レベルにおける非葉ノードの合計の最大値を求める方法

この記事では、二分木が与えられたときに、すべてのレベルの中から非葉ノード(子ノードを持つノード)の合計が最大となるレベルの合計値を求めるC++プログラムの作成方法を解説します。

問題の概要

二分木の各レベルごとに非葉ノードのデータ値の合計を計算し、その中で最も大きい合計値を出力します。

入力例

C++で二分木の各レベルにおける非葉ノードの合計の最大値を求める方法

出力例

9

解説

各レベルにおける非葉ノードの合計は以下のようになります。

レベル1: 4
レベル2: 1 + 2 = 3
レベル3: 9(4と7は葉ノードのため対象外)
レベル4: 0

この結果から、最大の合計値は「9」であることがわかります。

解決のアプローチ

この問題を解くには、二分木に対してレベル順走査(幅優先探索:BFS)を行い、各レベルの非葉ノードの合計を求めて、その最大値を記録していく必要があります。

具体的な手順は次のとおりです。

  1. キューを使ってレベル順にノードを処理します。
  2. 各ノードについて、左の子または右の子を持っているかどうかを確認します。子を持つノード(=非葉ノード)であれば、その値を現在のレベルの合計に加算します。
  3. レベル内のすべてのノードを処理したら、その合計がこれまでの最大値 maxSum を上回っていれば更新します。
  4. すべてのレベルの走査が終わった時点の maxSum が答えとなります。

なお、空の木(NULL)が渡された場合は0を返すようにしています。

実装例

上記の解法を実装したプログラムは以下のとおりです。

#include <bits/stdc++.h>
using namespace std;
struct Node {
    int data;
    struct Node *left, *right;
};
int maxLevelSum(struct Node* root){
    if (root == NULL)
        return 0;
    int maxSum = root->data;
    queue<Node*> q;
    q.push(root);
    while (!q.empty()) {
        int count = q.size();
        int levelSum = 0;
        while (count--) {
            Node* temp = q.front();
            q.pop();
            // 子を持つノード(非葉ノード)のみ合計に加算
            if (temp->left != NULL || temp->right != NULL)
                levelSum = levelSum + temp->data;
            if (temp->left != NULL)
                q.push(temp->left);
            if (temp->right != NULL)
                q.push(temp->right);
        }
        maxSum = max(levelSum, maxSum);
    }
    return maxSum;
}
struct Node* insertNode(int data) {
    struct Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return (node);
}
int main() {
    struct Node* root = insertNode(6);
    root->left = insertNode(1);
    root->right = insertNode(2);
    root->left->left = insertNode(4);
    root->left->right = insertNode(7);
    root->right->right = insertNode(9);
    root->right->right->left = insertNode(5);
    cout<<"The maximum sum of all non-leaf nodes at a level of the binary tree is "<<maxLevelSum(root);
    return 0;
}

実行結果

The maximum sum of all non-leaf nodes at a level of the binary tree is 9

計算量について

このアルゴリズムでは、各ノードを一度だけ訪問するため、時間計算量は O(N)(Nはノード数)、キューに格納されるノード数に比例して空間計算量も O(N) となります。木全体を効率よく走査できるため、大きな二分木に対しても実用的な手法です。

  1. C++で完全二分木の全ノードの合計を効率的に求める方法

    問題の概要 正整数 L が与えられ、これは完全二分木(パーフェクト・バイナリツリー)のレベル数を表しているとします。この木の葉ノードには、1 から n までの番号が順に割り当てられています(n は葉ノードの総数)。また、各親ノードの値は、その 2 つの子ノードの値の合計となります。 今回の課題は、この完全二分木に含まれるすべてのノードの値の合計を出力するプログラムを作成することです。 例として、次のような木を考えてみましょう。 この木の場合、すべてのノードの合計は 30 になります。 解法のアプローチ この問題を注意深く観察すると、求めるべきは全ノードの値の総和です。葉ノードには 1 から

  2. C++で二分木のすべてのノードのレベルを出力する方法

    二分木(バイナリツリー)が与えられたとき、各ノードに格納されたすべてのキーについて、そのノードが属するレベル(根をレベル1として数える)を出力するのが本記事の目的です。上記の木では、ノードは次のように配置されています。10 はレベル 1 3 と 211 はレベル 2 140、162、100、146 はレベル 3特定のキーが与えられた場合、プログラムはそのキーが属するレベルを出力できなければなりません。入出力例入力: 10 3 211 140 162 100 146 出力:     10 のレベルは 1     3