【C++】再帰を使わない二分木の中順(Inorder)トラバーサルの実装方法
二分木を中順(Inorder)でトラバースするとは、まず左部分木を訪問し、次にルート(根)ノード、最後に右部分木を訪問する手法のことです。特に二分探索木(BST)に対して中順トラバーサルを行うと、キーが昇順に出力されるという重要な性質があります。本記事では、再帰を使わずにスタックを活用して中順トラバーサルを実装するC++プログラムを紹介します。
アルゴリズム
再帰を使わない中順トラバーサルは、明示的なスタックを用いて以下の手順で実現します。
Begin
Function inOrder():
スタック s を宣言する
現在のノード current を root に設定する
current が NULL でない かつ スタックが空でない 間、以下を繰り返す
current が NULL でない間、以下を繰り返す
current をスタックの先頭にプッシュする
左の子ノードを current に設定する
current をスタックの先頭ノードに設定する
スタックの先頭ノードをポップする
current の値を出力する
右の子ノードを current に設定する
ルート・左ノード・右ノードに要素を挿入して木を構築する
inOrder() を呼び出して木をトラバースする
End.
サンプルコード
#include<bits/stdc++.h>
using namespace std;
struct n {
int d;
struct n* l;
struct n* r;
n (int d) {
this->d = d;
l = r = NULL;
}
};
void inOrder(struct n *root) {
stack<n *> s;
n *current = root;
while (current != NULL || s.empty() == false) {
while (current != NULL) {
s.push(current);
current = current->l;
}
current = s.top();
s.pop();
cout << current->d << " ";
current = current->r;
}
}
int main() {
struct n *root = new n(7);
root->l = new n(6);
root->r = new n(2);
root->l->l = new n(1);
root->l->r = new n(9);
inOrder(root);
return 0;
}
コードの解説
このプログラムでは、再帰呼び出しの代わりにスタックがトラバーサルの状態を管理します。処理の流れは以下のとおりです。
- 現在のノードから左方向へ進みながら、通過したノードをすべてスタックにプッシュしていきます。
- 左端に到達したら、スタックの先頭からノードをポップし、その値を出力します。
- ポップしたノードの右部分木へ移動し、スタックが空になるまで同じ処理を繰り返します。
再帰では呼び出しスタックが暗黙的に「戻るべきノード」を記憶していましたが、この実装ではそれを明示的なスタックで代替しています。そのため、深い木を扱う場合でも呼び出しスタックのオーバーフローを気にせずにトラバースできるのが利点です。
実行結果
1 6 9 7 2
このサンプルコードで構築される二分木は次の構造です。
7
/ \
6 2
/ \
1 9
中順トラバーサルは「左 → 根 → 右」の順でノードを訪問するため、出力は「1 → 6 → 9 → 7 → 2」となります。
-
二分法を用いて方程式の根を求めるC++プログラム
関数f(x)と2つの数a、bが与えられ、f(a)・f(b)<0を満たし、関数f(x)が区間[a, b]内に存在するとします。ここでの課題は、二分法(バイセクション法)を用いて、関数f(x)の区間aとbの間に存在する根の値を求めることです。 二分法とは? 二分法とは、「a」と「b」で定義された範囲内において、関数f(x)の根の値を求めるための数値計算手法の一つです。関数の根とは、その値を代入したときにf(x)=0となるような値xのことです。 例 方程式 F(x) = x^3 − 8 を考える この方程式は、x = 2 のとき F(x) = 2^3 − 8 = 0 となります。 したがって
-
【C++】二分木の中順走査(Inorder Traversal)を再帰的に実装する方法
木の走査(Tree Traversal)は、グラフ走査の一種であり、木に含まれるすべてのノードをそれぞれ一度だけ訪問(チェックまたは出力)する操作です。二分探索木における中順走査(Inorder Traversal、通りがけ順とも呼ばれます)では、「左の子 → 根 → 右の子」の順序で各ノードを訪問します。 二分木の中順走査の具体例を見てみましょう。次のような二分木が与えられたとします。 この二分木に対する中順走査の結果は次のとおりです。 中順走査の結果:1 4 5 6 8 それでは、中順走査を再帰的に実行するC++プログラムを見ていきましょう。 サンプルコード #include<i