データ構造における二分木の表現方法|配列と連結リストの違いを解説
コンピュータメモリ上での二分木の表現方法
ここでは、二分木をコンピュータのメモリ上でどのように表現するかについて解説します。表現方法には主に2種類あり、配列を使う方法と連結リスト(リンクリスト)を使う方法があります。
配列による表現
まず、次のような二分木を例に考えてみましょう。

配列による表現では、木の要素をレベル順(幅優先順)に走査しながら格納していきます。つまり、ノードを上のレベルから順番に保存する方式です。存在しない要素がある場合は、その位置を空白のまま残します。上記の木を配列で表現すると、次のようになります。
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 10 | 5 | 16 | - | 8 | 15 | 20 | - | - | - | - | - | - | - | 23 |
インデックス1には根(ルート)である「10」が格納されており、その2つの子「5」と「16」はそれぞれインデックス2と3に配置されます。子が存在しないノードについては、対応する位置が空白のままになっています。
親と子のインデックスを求める計算式
この表現方法では、次の式を使うことで、あるノードの子の位置を簡単に求められます。
$$child_{1}=2*parent$$
$$child_{2}=\lgroup2*parent\rgroup+1$$
逆に、子のインデックスから親の位置を求める場合は、次の式に従います。
$$parent=\begin{bmatrix}\frac{child}{2} \end{bmatrix}$$
このアプローチは、親や子のインデックスを数式だけで即座に計算できる点が大きな利点です。しかし一方で、メモリ効率の面では劣るという欠点があります。木が不完全な場合、使用されない空白領域が大量に発生してしまうためです。したがって、この表現方法は完全二分木や全二分木のような、ノードが密に詰まった木に適しています。
連結リストによる表現
もう一つの方法は、連結リストを使用するものです。この場合、各要素に対して個別のノードを作成し、各ノードはデータと左右の子へのポインタを持ちます。イメージは以下のようになります。

連結リストによる表現では、存在しない子のための無駄な領域を確保する必要がないため、ノードが疎な木でもメモリを効率的に利用できるというメリットがあります。
-
二分探索木の走査アルゴリズム完全解説:行順・先行順・後行順・レベル順をC++で実装
二分探索木の走査とはこの記事では、二分探索木(BST:Binary Search Tree)に格納されたキーを巡回するための4種類の走査アルゴリズムを解説します。具体的には、以下の4つです。行順(Inorder)走査:左部分木 → 根 → 右部分木の順に訪問先行順(Preorder)走査:根 → 左部分木 → 右部分木の順に訪問後行順(Postorder)走査:左部分木 → 右部分木 → 根の順に訪問レベル順(Level-order)走査:木の上から階層ごとに左から右へ訪問例として使用する木説明のために、次のような二分探索木を想定します。この木に対する各走査の結果は以下のようになります。行順走
-
二分木(バイナリツリー)のデータ構造と重要な性質を解説
二分木(バイナリツリー)とは、各ノードが持てる子ノードの数を最大2つに制限した木構造のデータ構造です。本記事では、この二分木が持つ重要な性質について、具体例とともにわかりやすく解説します。まず、次のような二分木を例に考えてみましょう。二分木の主な性質各レベルの最大ノード数:レベル「l」における最大ノード数は 2l−1 です。ここでいうレベルとは、根(ルート)からそのノードまでの経路上にあるノードの総数を指し、ルート自身も含みます。なお、ルートのレベルは1として扱います。木全体の最大ノード数:高さ h の二分木に含まれる最大ノード数は 2h−1 です。ここでいう高さとは、ルートから葉までの経路上