【C++】再帰を使わずに二分木を中順走査(In-order Traversal)するプログラム
二分木を中順(In-order)で走査する場合、まず左の部分木を訪問し、次に根(ルート)、最後に右の部分木を訪問します。中順走査では、キーが昇順に出力されるという特徴があります。この記事では、再帰を使わずに二分木を中順走査するC++プログラムを紹介します。
非再帰中順走査の仕組み
再帰を使わない中順走査では、スタックを利用します。大まかな手順は以下のとおりです。
- 現在のノードがNULLになるまで、ノードをスタックにpushしながら左の子へ移動します。
- 左端に到達したら、スタックの先頭ノードをpopしてその値を出力します。
- 取り出したノードの右の子へ移動し、スタックが空かつ現在のノードがNULLになるまで1〜2を繰り返します。
アルゴリズム
Begin
構造体 n を宣言する。
整数型のメンバ d を宣言する。
構造体 n へのポインタ l を宣言する。
構造体 n へのポインタ r を宣言する。
構造体 n のコンストラクタを宣言する。
引数として整数変数 d を受け取る。
this->d = d
l = r = NULL
関数 inOrder(struct n *root) を宣言する。
スタック s を宣言する。
構造体 n へのポインタ current を宣言する。
n *current = root で初期化する。
while (current != NULL || s.empty() == false)
while (current != NULL)
s.push(current)
current = current->l
current = s.top()
s.pop()
current->d を出力する。
current = current->r
木の各ノードに値を挿入する。
inOrder(root) を呼び出して木を走査する。
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(6);
root->l = new n(4);
root->r = new n(7);
root->l->l = new n(8);
root->l->r = new n(5);
root->r->l = new n(9);
root->r->r = new n(10);
inOrder(root);
return 0;
}
コードのポイント
- 構造体
nは、ノードの値dと左右の子へのポインタl・rを持ちます。 - コンストラクタでノード生成時に値を設定し、子ポインタをNULLで初期化しています。
inOrder()関数ではstack<n *>を使い、左方向へ進みながらノードを一時的に退避させます。- 左端に到達したらスタックからノードを取り出して値を出力し、右の部分木へ移動します。
実行結果
8 4 5 6 9 7 10
この出力は、木のノードを「左→根→右」の順に訪問した結果であり、キーが昇順に並んでいることが確認できます。
-
【C++】二分木の中順走査(Inorder Traversal)を再帰的に実装する方法
木の走査(Tree Traversal)は、グラフ走査の一種であり、木に含まれるすべてのノードをそれぞれ一度だけ訪問(チェックまたは出力)する操作です。二分探索木における中順走査(Inorder Traversal、通りがけ順とも呼ばれます)では、「左の子 → 根 → 右の子」の順序で各ノードを訪問します。 二分木の中順走査の具体例を見てみましょう。次のような二分木が与えられたとします。 この二分木に対する中順走査の結果は次のとおりです。 中順走査の結果:1 4 5 6 8 それでは、中順走査を再帰的に実行するC++プログラムを見ていきましょう。 サンプルコード #include<i
-
二分木の先行順(プレオーダー)走査を再帰的に実行するC++プログラム
二分木の先行順走査とは木の走査(トラバーサル)はグラフ走査の一種であり、木に含まれるすべてのノードをそれぞれ一度だけ訪れて処理を行うことを指します。二分探索木における先行順走査(プレオーダー走査)では、「根 → 左部分木 → 右部分木」の順序で各ノードを訪問するのが特徴です。次のような二分木を例に考えてみましょう。この二分木に対する先行順走査の結果は 6 4 1 5 8 となります。ここからは、この先行順走査を再帰的に実行するC++プログラムを紹介します。C++による実装例#include<iostream> using namespace std; struct node {