C++で二分木を倍化(ダブルツリー)する方法:サンプルコード付きでわかりやすく解説
このチュートリアルでは、与えられた二分木を「倍化」する方法について学びます。二分木の倍化とは、各ノードの左側に同じ値を持つ新しいノードを挿入し、元のノードをその右側に残す操作のことです。
それでは、問題を解くための手順を順番に見ていきましょう。
アルゴリズムの手順
- ノードクラスを作成します。
- ダミーデータを使って木を初期化します。
- 木を倍化するための再帰関数を記述します。
- 再帰的に木を走査します。
- 結果を出力して確認します。
再帰関数の処理の流れは以下の通りです。
- まず、左右の子に対して再帰的に処理を行います。
- 現在の左の子ノードを一時変数に保存します。
- 現在のノードと同じ値を持つ新しいノードを作成し、それを左の子として設定します。
- 新しく作成したノードの左に、保存しておいた元の左の子を接続します。
C++での実装例
実際のコードを見てみましょう。
#include <bits/stdc++.h>
using namespace std;
class node {
public:
int data;
node* left;
node* right;
};
node* newNode(int data) {
node* Node = new node();
Node->data = data;
Node->left = NULL;
Node->right = NULL;
return Node;
}
void doubleTree(node* Node) {
node* oldLeft;
if (Node == NULL) return;
doubleTree(Node->left);
doubleTree(Node->right);
oldLeft = Node->left;
Node->left = newNode(Node->data);
Node->left->left = oldLeft;
}
void printTree(node* node) {
if (node == NULL) {
return;
}
printTree(node->left);
cout << node->data << " ";
printTree(node->right);
}
int main() {
node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
cout << "Original Tree" << endl;
printTree(root);
cout << endl;
doubleTree(root);
cout << "Double Tree" << endl;
printTree(root);
cout << endl;
return 0;
}コードのポイント
doubleTree 関数では、まず再帰的に左右の部分木を処理してから、現在のノードの複製を挿入しています。この順序が重要で、先に子を処理することで、挿入された複製ノードが後続の再帰処理に影響されることなく正しく動作します。
実行結果
上記のコードを実行すると、次のような出力が得られます。
Original Tree 2 1 3 Double Tree 2 2 1 1 3 3
出力から分かるように、元の木の中順走査(in-order traversal)の結果は「2 1 3」ですが、倍化後は各ノードの複製が直前に現れるため「2 2 1 1 3 3」となります。このように中順走査を使うことで、倍化が正しく行われたかどうかを簡単に確認できます。
まとめ
このチュートリアルでは、再帰を使って二分木を倍化する方法を紹介しました。ポイントは、左右の部分木を先に再帰的に処理し、その後に現在のノードの複製を左の子として挿入することです。この手法は計算量 O(n)、空間計算量も木の高さ分のスタック領域で済むため、効率的なアプローチと言えます。
このチュートリアルについて質問がある場合は、コメント欄でお気軽にお尋ねください。
-
C++で二分木の奇数レベルにあるノードを出力するプログラム
このチュートリアルでは、与えられた二分木(バイナリツリー)の中から、奇数レベルに存在するノードを出力するC++プログラムについて解説します。 本プログラムでは、ルートノードのレベルを「1」と定義し、それ以降のレベルは交互にカウントしていきます。つまり、レベル1・3・5…といった奇数番目の階層に属するノードが出力の対象となります。 例として、以下のような二分木が与えられた場合を考えてみましょう。 この二分木の場合、奇数レベルに存在するノードは 1, 4, 5, 6 となります。 アルゴリズムの考え方 実装には再帰呼び出しを利用します。ルートから探索を開始し、現在のレベルが奇数かどうかをブール
-
C++でAVL木(AVLツリー)を実装する方法:回転操作とサンプルコードを徹底解説
AVL木とは AVL木(AVL Tree)は、自己平衡型二分探索木(Self-balancing Binary Search Tree)の一種です。すべてのノードにおいて、左部分木と右部分木の高さの差が「1以下」に保たれるという性質を持っています。この平衡条件により、木が片側に偏って成長することを防ぎ、検索・挿入・削除といった操作を常に効率的(O(log n))に行うことができます。 木の回転(Tree Rotation)とは 木の回転とは、要素の順序(ソート順)を崩すことなく木の構造を変更する操作のことです。あるノードを一段上へ移動させ、別のノードを一段下へ移動させることで実現されます。 回