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

C++で二分木の後順走査におけるn番目のノードを検索する方法


問題概要

この問題では、二分木と整数Nが与えられます。求められているのは、二分木の後順走査(ポストオーダートラバーサル)におけるN番目のノードを見つけることです。

二分木とは、各ノードが最大2つの子ノードを持つことができる特殊な木構造です。

トラバーサル(走査)とは、木に含まれるすべてのノードを順に訪問する処理のことで、訪問時にノードの値を出力することもあります。

具体例を使って問題を理解しましょう。

入力

N = 6

対象となる二分木は以下の通りです。

        1
       / \
      2   3
     / \ / \
    4  5 6  7

出力

3

説明

この木の後順走査の順序は「4, 5, 2, 6, 7, 3, 1」です。したがって、6番目に訪問されるノードの値は「3」となります。

解決アプローチ

この問題の鍵となるのは、再帰呼び出しを利用した二分木の後順走査です。各再帰呼び出しでは、まず左部分木に対してpostOrder()を呼び出し、続いて右部分木に対してpostOrder()を呼び出し、最後に現在のノード(ルート)を訪問します。

走査の過程では、訪問済みノードの数をカウントしていき、そのカウントがNと一致したノードの値を出力します。

この解決策の動作を示すプログラムは以下の通りです。

実装例

#include <iostream>
using namespace std;

struct Node {
    int data;
    Node* left;
    Node* right;
};

Node* newNode(int val) {
    Node* node = new Node;
    node->data = val;
    node->left = NULL;
    node->right = NULL;
    return node;
}

void postOrder(Node* root, int N, int& counter) {
    if (root == NULL || counter >= N)
        return;
    // 左部分木を走査
    postOrder(root->left, N, counter);
    // 右部分木を走査
    postOrder(root->right, N, counter);
    // 現在のノードを訪問
    counter++;
    if (counter == N)
        cout << N << "番目のノードの値: " << root->data << endl;
}

int main() {
    Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
    root->right->right = newNode(7);

    int N = 6;
    int counter = 0;
    cout << "後順走査: 4 5 2 6 7 3 1" << endl;
    postOrder(root, N, counter);
    return 0;
}

出力

後順走査: 4 5 2 6 7 3 1
6番目のノードの値: 3

計算量の評価

時間計算量:二分木の各ノードを最大1回ずつ訪問するため、O(n) となります。

空間計算量:再帰呼び出しのスタックが木の高さ分必要となるため、最悪の場合(木が大きく偏っている場合)は O(n)、バランスの取れた木であれば O(log n) となります。


  1. C++で二分木の最大垂直和を求める方法

    はじめに二分木が与えられたとき、垂直順序走査における各垂直列のノード値の合計を計算し、その中から最大値を求めて出力するのが本記事の課題です。例として、以下のような二分木を考えてみましょう。この二分木を垂直順序走査すると、各列の合計は次のようになります。4 2 1 + 5 + 6 = 12 3 + 8 = 11 7 9各列の合計の中で最大となるのは 12 です。アルゴリズムの考え方アプローチはシンプルです。幅優先探索(BFS)を用いて垂直順序走査を行い、各ノードに水平距離を割り当てます。ルートの水平距離を 0 とし、左に移動するごとに -1、右に移動するごとに +1 とします。同じ水平距離を持つ

  2. 与えられた二分木の後順(ポストオーダー)再帰走査を実行するC++プログラム

    木構造の走査(トラバーサル)はグラフ走査の一種であり、木の中の各ノードを正確に一度だけ訪問して確認・出力する操作を指します。二分探索木の後順走査(ポストオーダー走査)では、木の各ノードを「左 → 右 → 根」の順序で訪問します。二分木の後順走査の例を以下に示します。次のような二分木が与えられたとします。この場合、後順走査の結果は次のようになります。後順走査の出力:1 5 4 8 6後順再帰走査を行うC++プログラム後順(ポストオーダー)再帰走査を実行するプログラムは以下の通りです。#include<iostream> using namespace std; struct node