典型的なデータ構造 - スタック/キュー/リンク リスト、ハッシュ検索、バイナリ ツリー (BT)、クルー バイナリ ツリー、バイナリ ソート ツリー (BST ツリー)、バランス バイナリ ツリー (AVL ツリー)、赤黒ツリー (RB ツリー)

目次

代表的なデータ構造のリスト

スタック/キュー/リンクリスト

二分木

手がかり二分木

バイナリソートツリー

バランス二分木 (AVL ツリー)

赤黒い木

他の樹種と用途の紹介


代表的なデータ構造のリスト

スタック/キュー/リンクリスト

説明省略。

いくつかの基本的な単純な実装は/数据结构简单实现/参照フォルダーにあります。

ツリーの基本概念(定義、基本操作、プロパティ、記憶構造など)、バイナリツリー(定義、基本操作、記憶、走査など)、バランスバイナリツリー、赤黒ツリーなどを以下に示します。

引用元:ツリーとバイナリ ツリーの基本概念_Qingpingzhimo のブログ - CSDN ブログ

ツリーは 1 つ以上のノードで構成され、ルートと呼ばれる特殊なノードがあり、これは n (n>=0) 個のノードの有限集合です。n=0 の場合、空のツリーと呼ばれます。n>0 の場合、有限集合の要素は階層データ構造を形成します。

アセット/70.jpeg

木のいくつかの概念

  • ノード次数: ノードが持つサブツリーの数。たとえば、A の次数は 2、B の次数は 1、C の次数は 3 です。
  • ツリーの高さ: ツリーの深さとも呼ばれ、ツリー内のノードの最大レベル。
  • 順序付きツリー: ツリー内のノードのサブツリー間の順序が重要であり、位置を自由に交換することはできません。
  • 順序なしツリー: ツリー ノードのサブツリー間の順序は重要ではありません。自由に位置を入れ替えることができます。
  • フォレスト: 0 個以上の互いに素なツリーのコレクション。

引用元:「データ構造チュートリアル」。

木のいくつかの性質

  1. 空ではないツリー内のノードの総数は、ツリー内のすべてのノードの次数の合計に 1 を加えたものに等しくなります。
  2. 次数 k の空ではないツリーの i 番目のレベルには、最大でも k^(i-1) 個のノードがあります (i ≥ 1)。
  3. 深さ h の k 分ツリーには、最大で (k^h - 1)/(k - 1) 個のノードがあります。
  4. n ノードを持つ k 分木の最小の深さは、log_k(n*(k - 1)) + 1 です。n 個のノードを含むバイナリ ツリーの高さは、少なくとも log_2(n) + 1 です。

基本的なツリー操作

  1. 空のツリー T を作成します。
  2. ノード x が配置されているツリーのルート ノードを見つけます。または、ツリー T のルート ノードを見つけます。
  3. ツリー T でノード x の親ノードを見つけます。
  4. ツリー T 内のノード x の i 番目の子ノードを見つけます。
  5. ツリー T 内のノード x の右側にある兄弟ノードを見つけます。
  6. S をルート ノードとするツリーを、ツリー T のノード x の i 番目の子ノード位置に挿入します。
  7. ツリー T 内のノード x の i 番目のツリーを削除します。
  8. ツリーを走査し、ツリーのすべてのノードを特定の順序で走査し、すべてのノードで構成されるシーケンスを取得します。

ツリーストレージ

チェーンストレージが主に使用されます。ノード自体のデータ情報を格納するだけでなく、ツリー内のノード間の接続関係も格納構造に反映する必要があります。

  • マルチリンクリスト表現:固定長リンク番号と可変長リンク番号に分けられます。

    前者:

    1

    後者:

    2

  • トリプルリンクリスト表現:

    3

二分木

ツリーとバイナリ ツリーの基本概念_Qingpingzhimo のブログ - CSDN ブログ

引用元:「データ構造チュートリアル」。

二分木構造は、コンピュータ分野におけるさまざまな実際的な問題を解決するために広く使用されています。たとえば、バイナリ ツリーは、並べ替え、検索、データベース管理システム、人工知能などの多くの側面で強力かつ効果的なサポートを提供します。

各ノードには最大 2 つのサブツリーがあります。二分木では、ノードの左右の部分木は厳密に区別されており、それらの順序を自由に逆転させることはできません。したがって、二分木は順序付けられた木です。

バイナリ ツリーは、完全なバイナリ ツリーと完全なバイナリ ツリーに分類できます。

二分木の基本操作

4

二分木記憶構造

  • シーケンシャル ストレージ構造: シーケンシャル ストレージ構造にはいくつかの固有の欠陥があり、バイナリ ツリーの挿入と削除が不便で、効率が比較的低くなります (線形テーブルの固有の欠点)。

    5

  • チェーン収納構造:より適切でより広い。2 つのリンク リスト構造と 3 つのリンク リスト構造の 2 つのタイプ。

    バイナリ リンク リスト構造: リンク リストの各リンク ポイントは 3 つのフィールド、つまりデータ フィールドと 2 つのポインター フィールドで構成され、後者はそれぞれノードの左側と右側のノードのストレージ アドレスを示します。

    6

    Trident リンク リスト構造: バイナリ リンク リスト構造と比較して、親ノードを指すポインタ フィールドが追加されているため、バイナリ ツリー内のノードの親ノードを検索するときに、バイナリ ツリー全体をトラバースする必要がありません。二分木。時間(検索時間など)のためのスペースです。

バイナリ ツリーとツリー トラバーサル

バイナリ ツリーに対する操作の多くは、ほぼバイナリ ツリー トラバーサルに基づいています。二分木は非線形構造であるため、二分木内のすべてのノードが線形順序で配置されるように規則を見つける必要があります。これをトラバーサルと呼びます。

シンボル D、L、および R を使用して、ルート ノードにアクセスする、ルート ノードの左側のサブツリーを横断する、およびルート ノードの右側のサブツリーを横断するという 3 つのプロセスをそれぞれ表し、最初の左と最初のサブツリーの順序を制限するとします。メソッド: DLR、LDR、および LRD (それぞれ、事前順序トラバーサル、順序内トラバーサル、および後続トラバーサルと呼ばれます)。階層的な走査順序もあります。

トラバーサルは再帰的に実行できます (大きなツリーではスタック オーバーフローが発生しやすくなります)。非再帰メソッドは通常、スタック構造を利用します。

以下は、順序走査順序で走査されるプログラムの例です。

7

レベルによるトラバーサル (または幅優先トラバーサル)。つまり、トラバースされるバイナリ ツリーが空でない場合、最初のレベル、2 番目のレベル... バイナリ ツリーの最後のレベルまで順番にアクセスされます。レベルは左から右の順に進みます。このメソッドは通常、キューを使用して実装されます。以下はプログラム例です。

8

走査シーケンスからバイナリ ツリーを復元する

3 つのステップ:

アセット/9.jpg

手がかり二分木

二分木のノードに手がかりを追加した二分木を手がかり付き二分木と呼びます。n 個のノードを持つバイナリ ツリーの場合、バイナリ チェーン ストレージ構造には n+1 個の空のリンク フィールドがあります。これらの空のリンク フィールドは、ノードの先行ノードと後続ノードのポインタを特定の走査順序で格納するために使用されます。これらのポインタは次のとおりです。を手がかりと呼び、二分木に手がかりを加えたものを手がかり二分木と呼びます。

バイナリソートツリー

引用元:「データ構造チュートリアル」。

バイナリソートツリーはソート、検索/取得に使用され、検索の時間効率を大幅に向上させることができます(一般に、クエリ効率はリンクリスト構造よりも高くなります)。二分ソート木は二分探索木とも呼ばれます。完了する必要がある機能が挿入、削除、検索である場合、バイナリ ソート ツリーはこれまでに研究されたどのデータ構造よりも優れたパフォーマンスを発揮するという人もいます。

引用元:バイナリソートツリー (二分探索ツリー) および C 言語実装 (biancheng.net)

バイナリ ソート ツリーは、空のバイナリ ツリーであるか、次の特性を備えています。

  • バイナリソートツリーでは、ルートノードに左サブツリーがある場合、左サブツリー上のすべてのノードの値はルートノードの値より小さくなります。
  • バイナリソートツリーでは、そのルートノードに右サブツリーがある場合、右サブツリー上のすべてのノードの値はルートノードの値より大きくなります。
  • バイナリ ソート ツリーの左側と右側のサブツリーもバイナリ ソート ツリーである必要があります。

下図に示すように、二値ソートツリーです。

アセット/103FJ439-0.png

引用元:「データ構造チュートリアル」。

バイナリ ソート ツリーにデータを挿入する場合も、バイナリ ソート ツリーの原則に従う必要があります。新しい要素がバイナリソートツリーに挿入されるたびに、その要素に対応するノードがリーフノードの位置に挿入され、バイナリツリー内の他のノードは挿入プロセス中に移動されません。データ要素の列は必ずしも値の大きさに従って配列されているわけではありませんが、二分ソート木に構築された後、二分ソート木を順に走査して得られる配列は、値の大きさに従って配列された配列になります。値の。

バランス二分木 (AVL ツリー)

引用元:バランス バイナリ ツリー (AVL ツリー) および C 言語実装 (biancheng.net)

バランスの取れたバイナリ ツリー。AVL ツリーとも呼ばれます。これは実際には、次の 2 つの特性に従うバイナリ ツリーです。

  • 各サブツリーの左側のサブツリーと右側のサブツリーの深さの差は 1 を超えることはできません。
  • バイナリ ツリー内の各サブツリーは、バランスの取れたバイナリ ツリーである必要があります。

実際、バイナリ ツリーに基づいて、ツリー内の各サブツリーが左のサブツリーと右のサブツリーの深さの差が 1 を超えないことを満たしている場合、このバイナリ ツリーはバランスのとれたバイナリ ツリーです。

二分木の各ノードの左側のサブツリーの深さと右側のサブツリーの深さの差がノードのバランス係数として定義されるため、バランスの取れた二分木の各ノードのバランス係数は 1 のみになります。 、0 または -1。

引用元:「データ構造チュートリアル」。

二分ソート木の形状は事前に予測できず、非常に恣意的であり、非常にバランスの悪い二分木が得られることが多く、深さの差が大きくなるほど計算時間が長くなり、利点が失われます。この二分ソート木の欠点を克服するには、二分ソート木が常にバランスの取れた状態になるように、ノードの挿入や削除をしながら二分木の形態構造に必要な調整を行う必要があります。

n 個のノードを持つバランスのとれたツリーの深さは、同じノード数を持つ理想的なバランスのとれたツリーの深さよりも 45% 以上大きくならないことが理論的に証明されています。したがって、再バランスされたツリー上の検索操作は理想的なバランスの取れたツリーよりも遅くなりますが、通常は任意に生成されたバイナリソートツリー上の検索操作よりもはるかに高速であり、その時間計算量は依然として O(Log_2(n ))。

赤黒い木

Red-Black Tree (RB-Tree)_Qingpingzhimo のブログ - CSDN ブログから引用 

赤黒木は二分探索木です。

赤黒木とAVL木の比較

  • ノードの挿入によってツリーの不均衡が生じる場合、AVL と RB-Tree はどちらも最大 2 回の回転操作のみを必要とします。つまり、両方とも O(1) ですが、ノードの削除によってツリーの不均衡が生じる場合は、最悪の場合です。シナリオ AVL では、削除されたノードからルート ノードまでのパス上のすべてのノードのバランスを維持する必要があるため、必要な回転の大きさは O(logN) ですが、RB-Tree では最大 3 回の回転しか必要とせず、必要なのは O( 1) 複雑さ。
  • ただし、赤黒ツリーは AVL ツリーほどバランスが取れていないため、赤黒ツリーの検索パフォーマンスは AVL ツリーよりも悪く、この検索パフォーマンスの悪さは、挿入および削除時の回転パフォーマンスに見合う価値があります。このため、STL でのマップやセットなど、AVL ツリーの代わりに赤黒ツリーが多くの状況で使用されます。したがって、多数のノードの挿入と削除が必要なシナリオでは、RB-Tree の方が効率的です当然、AVL はバランスが取れているため、検索効率が高くなります
他の樹種と用途の紹介

おすすめ

転載: blog.csdn.net/Staokgo/article/details/132922474