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

C++で二分木のすべての内部ノードを出力する方法

この記事では、与えられた二分木からすべての内部ノードを見つけて出力する方法を解説します。

二分木と内部ノードとは

二分木(バイナリツリー)とは、各ノードが最大2つの子ノードを持つことができる木構造のデータ構造です。ノードは子をまったく持たないこともあれば、1つだけ持つこと、2つ持つこともあります。

内部ノードとは、少なくとも1つの子ノードを持つノードのことを指します。言い換えると、葉ノード(子を持たないノード)以外のノードがすべて内部ノードです。

具体例

次のような二分木を考えてみましょう。

C++で二分木のすべての内部ノードを出力する方法

この木の場合、子ノードを持っているのは 7、4、9 の3つのノードなので、出力は以下のようになります。

出力: 7 4 9

解決アプローチ:BFS(幅優先探索)

この問題は、BFS(幅優先探索)を使って二分木を走査することで解けます。手順は以下の通りです。

  • ルートノードをキューに追加します。
  • キューからノードを1つずつ取り出します。
  • 取り出したノードが子ノードを少なくとも1つ持っている場合(=内部ノードの場合)、その値を出力します。
  • 存在する子ノードをすべてキューに追加し、キューが空になるまでこの処理を繰り返します。

C++での実装例

上記のロジックを実装したコードがこちらです。

#include <bits/stdc++.h>
using namespace std;

struct Node {
    int data;
    Node *left, *right;
    Node(int data){
        left = right = NULL;
        this->data = data;
    }
};

void printNonLeafNodes(Node* root) {
    queue<Node*> treeNodes;
    treeNodes.push(root);
    while (!treeNodes.empty()) {
        Node* curr = treeNodes.front();
        treeNodes.pop();
        bool isInternal = 0;
        if (curr->left) {
            isInternal = 1;
            treeNodes.push(curr->left);
        }
        if (curr->right) {
            isInternal = 1;
            treeNodes.push(curr->right);
        }
        if (isInternal)
            cout<<curr->data<<"\t";
    }
}

int main() {
    Node* root = new Node(43);
    root->left = new Node(12);
    root->right = new Node(78);
    root->left->left = new Node(4);
    root->right->left = new Node(9);
    root->right->right = new Node(1);
    root->right->right->right = new Node(50);
    root->right->right->left = new Node(25);
    cout<<"All internal Nodes of the binary tree are :\n";
    printNonLeafNodes(root);
    return 0;
}

コードのポイント

  • Node 構造体で、ノードの値と左右の子へのポインタを保持します。
  • printNonLeafNodes 関数では、キューを使ってBFS走査を行い、isInternal フラグによってそのノードが内部ノードかどうかを判定しています。
  • 左の子または右の子が存在すればフラグを立てて値を出力し、同時にその子をキューへ追加して走査を続けます。

実行結果

All internal Nodes of the binary tree are −
43 12 78 1

このサンプルツリーでは、43・12・78・1 の4つのノードが子を持っているため、これらが出力されます。計算量は各ノードを一度ずつ訪問するため O(n)、空間計算量も最悪ケースで O(n) となります。

  1. C++で二分木のノードを葉ノードになった順に出力する方法

    問題概要 二分木が与えられたとき、まずその葉ノード(リーフノード)を出力します。次に、出力した葉ノードを木から取り除き、新たに葉ノードとなったノードを出力します。この操作を、木の中にノードが一つも残らなくなるまで繰り返します。 例 以下のような二分木を例に考えてみましょう。 まず最下層の葉ノード「6 7 9 13 14」を出力して取り除き、次に新たな葉ノードとなった「3 4」を出力、続いて「2」、最後に根ノード「1」を出力します。したがって、この問題の出力は以下のようになります。 6 7 9 13 14 3 4 2 1 アプローチ この問題では、DFS(深さ優先探索)を用いたアプロ

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

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