C++のdeleteキーワードを使って二分木(バイナリツリー)を安全に削除する方法
C++では、デストラクタとdeleteキーワードを組み合わせることで、二分木(バイナリツリー)全体を再帰的に解放できます。まずは、int型のデータと左右の子ノードへのポインタを持つクラスで二分木を定義してみましょう。ここでは、クラスのすべてのメンバをpublicとしています。
class btree_node {
public:
int data;
btree_node* leftChild;
btree_node* rightChild;
};ノードの生成:コンストラクタ
新しいノードを作成するためのコンストラクタは、int型の値を引数として受け取り、新しく生成されたノードにその値を代入します。leftChildとrightChildはNULLで初期化されます。
btree_node(int data){
this->data = data;
this->leftChild = NULL;
this->rightChild = NULL;
}メモリの解放:デストラクタ
デストラクタが呼び出されると、deleteキーワードを使って左の子ノードと右の子ノードが削除されます。この仕組みにより、削除処理は自動的に子孫ノードへと再帰的に伝播していきます。
~btree_node(){
delete leftChild;
delete rightChild;
cout << this->data << " is being deleted"<<endl;
}木全体の削除を実行する
木全体の削除をトリガーするには、ルートノードに対してdeleteを呼び出すだけです。ルートの左部分木と右部分木も連鎖的に削除されるため、個別に各ノードを解放する必要はありません。
delete root;
サンプルコード
それでは、deleteキーワードを使用して二分木を削除する実際の実装例を見てみましょう。
#include <iostream>
using namespace std;
class btree_node {
public:
int data;
btree_node* leftChild;
btree_node* rightChild;
btree_node(int data){
this->data = data;
this->leftChild = NULL;
this->rightChild = NULL;
}
~btree_node(){
delete leftChild;
delete rightChild;
cout << this->data << " is being deleted"<<endl;
}
};
int main(){
btree_node* root = new btree_node(2);
btree_node* node1 = new btree_node(4);
btree_node* node2 = new btree_node(6);
btree_node* node3 = new btree_node(8);
btree_node* node4 = new btree_node(10);
root->leftChild = node1;
root->rightChild = node2;
node1->leftChild = node3;
node1->rightChild = node4;
delete root;
return 0;
}出力結果
上記のコードを実行すると、次のような出力が得られます。
8 is being deleted 10 is being deleted 4 is being deleted 6 is being deleted 2 is being deleted
出力を見ると、葉に近いノードから順に削除されていることがわかります。これは、デストラクタ内で先に子ノードをdeleteしてから自身のデータを出力しているため、木の事後順(ポストオーダー)走査と同じ順序でメモリ解放が行われるからです。この手法を使えば、ルートをdeleteするだけで木全体のメモリを確実に解放でき、メモリリークを防ぐことができます。
-
C++で二分木を剪定する:1を含まない部分木を削除する再帰アルゴリズム
問題概要二分木のルートノード root が与えられ、すべてのノードの値は 0 または 1 のいずれかであるとします。この木から、1 を含まないすべての部分木を削除した結果の木を求めるのが目的です。たとえば、次のような木が与えられた場合 −解決のためのアプローチこの問題は、再帰的な手法を用いて以下の手順で解決できます −ノードを引数として受け取る再帰メソッド solve() を定義します。処理の流れは次のとおりです −ノードが null の場合は、null を返しますノードの左の子に対して solve(左の子) を実行し、その結果を左の子に代入しますノードの右の子に対して solve(右の子)
-
C++で二分木における最も近い葉ノードまでの距離を求める方法
二分木が与えられ、その葉ノードはそれぞれ異なるレベルに存在するとします。さらに、あるノードを指すポインタが与えられ、そのノードから最も近い葉ノードまでの距離を求める必要があります。例として、次のような二分木を考えてみましょう。この木における葉ノードは 2、-2、6 の3つです。もしポインタがノード -5 を指している場合、-5 から最も近い葉ノードまでの距離は 1 となります。解決のアプローチこの問題を解くには、次の手順で考えます。まず、指定されたノードを根とする部分木を走査し、その部分木内で最も近い葉ノードを見つけて距離を記録します。次に、木の根から全体を走査します。ノード x が左部分木に