記事ディレクトリ
1. 木
1. 木とは何ですか?
ツリーは非線形データ構造であり、n (n>=0) 個の限定されたノードで構成される一連の階層関係です。
- サブツリーが互いに素である
- ルート ノードを除き、各ノードには親ノードが 1 つだけあります。
- N 個のノードを持つツリーには N-1 個のエッジがあります。
2. 樹木に関する概念
ノードの次数: ノードに含まれる部分木の数をノードの次数と呼びます; 上図に示すように、A の次数は 3 です
リーフノードまたはターミナルノード: 次数 0 のノードをリーフ ノードと呼びます; 上図に示すように: J、F、K、L、H、I などのノードがリーフ ノードです。
非終端ノードまたはブランチノード: 次数が 0 でないノード; 上図に示すように: B、C、D、E、G などのノードが分岐ノードです。
親ノードまたは親ノード: ノードに子ノードが含まれる場合、このノードはその子ノードの親ノードと呼ばれます; 上の図に示すように: A は B の親ノードです
子ノードまたは子ノード: ノードに含まれるサブツリーのルート ノードは、そのノードの子ノードと呼ばれます; 上の図に示すように: B は A の子ノードです
兄弟ノード: 同じ親ノードを持つノードは兄弟ノードと呼ばれます; 上に示すように: B と C は兄弟ノードです。
木の程度: ツリーでは、最大のノードの次数がツリーの次数と呼ばれます。上に示すように、ツリーの次数は 3 です。
ノードレベル: ルートの定義から開始すると、ルートは第 1 レベル、ルートの子ノードは第 2 レベル、というようになります。
木の高さまたは深さ: ツリー内のノードの最大レベル。上に示すように、ツリーの高さは 4 です。
いとこノード: 親が同じレベルにあるノードは互いにいとこです; 上の図に示すように: F と G は互いに兄弟ノードです。
ノードの祖先: ルートからノードまでの分岐上のすべてのノード。上の図に示すように: A はすべてのノードの祖先です。
子孫: 特定のノードをルートとするサブツリー内のノードは、そのノードの子孫と呼ばれます。上に示すように、すべてのノードは A の子孫です。
森: m (m>0) 個の互いに素なツリーの集合をフォレストと呼びます。
3. 木の表現
ツリー構造は線形テーブルよりも複雑です。保存するときは、値の範囲とノード間の関係の両方を保存する必要があります。ツリーを表現するには、親表現、子表現、子親表現など、さまざまな方法があります。および子供の兄弟の代理など。最も一般的に使用されるのは、子兄弟表記です。
//孩子兄弟表示法
typedef int DataType;
struct Node
{
struct Node* firstChild; // 第一个孩子结点
struct Node* nextBrother; // 指向其下一个兄弟结点
DataType data; // 结点中的数据域
};
2.二分木
1. 二分木の概念
バイナリ ツリーは有限のノードのセットで、空であるか、ルート ノードと左サブツリーおよび右サブツリーと呼ばれる 2 つのバイナリ ツリーで構成されます。
- 二分木には次数が 2 より大きいノードはありません
- 二分木の部分木は左右の部分木に分割でき、順序を逆にすることはできないため、二分木は順序付き木となります。
2. 二分木のいくつかの状況
バイナリ ツリーは次の状況で構成されます。
空のツリー:
ルート ノードのみ:
左側のサブツリーのみ:
右のサブツリーのみ:
左右のサブツリーの両方:
3. 特殊な二分木
完全なバイナリ ツリー: バイナリ ツリー 各層のノードの数が最大に達すると、バイナリ ツリーは完全なバイナリ ツリーになります。つまり、バイナリ ツリーのレベル数が K、ノードの総数が の場合、それは完全なバイナリ ツリーです。
完全なバイナリ ツリー: 完全なバイナリ ツリーは非常に効率的なデータ構造であり、完全なバイナリ ツリーは完全なバイナリ ツリーから派生します。深さ K でノードが n のバイナリ ツリーの場合、各ノードが深さ K の完全なバイナリ ツリー内の 1 から n までの番号が付けられたノードと 1 対 1 で対応する場合にのみ、完全なバイナリ ツリーと呼ばれます。
完全なバイナリ ツリーは、特別な種類の完全なバイナリ ツリーです。
4. 二分木の性質
- ルート ノードのレベル数が 1 に指定されている場合、空ではないバイナリ ツリーの i 番目のレベルには最大 2 (i-1)個のノードが存在します。
- ルート ノードのレベル数が 1 に指定されている場合、深さ h の二分木の最大ノード数は 2 h -1 になります。
- 任意の二分木について、次数 0 の葉ノードの数が n 0 で、次数 2 の分岐ノードの数が n 2である場合、n 0 =n 2 +1となります。
- ルート ノードのレベル数が 1 に指定されている場合、n ノードを持つ完全なバイナリ ツリーの深さは、 h= log 2 (n + 1) log _ 2 ^ (n+1)ログ_ _2(n+1 )。
- n 個のノードを持つ完全なバイナリ ツリーの場合、すべてのノードが上から下、左から右の配列順序で 0 から始まる番号が付けられている場合、シリアル番号 i のノードについては次のようになります。
- i>0 の場合、位置 i のノードの親番号: (i-1)/2; i=0、i はルート ノード番号であり、親ノードはありません
- 2i+1<n の場合、左の子の番号: 2i+1, 2i+1>=n それ以外の場合、左の子はありません
- 2i+2<n の場合、右側の子の番号: 2i+2, 2i+2>=n それ以外の場合は右側の子はありません
5. バイナリツリーの記憶構造
バイナリ ツリーは通常、シーケンシャル構造とチェーン構造の 2 つの構造を使用して格納できます。
順次ストレージ:
シーケンシャル構造ストレージでは、ストレージに配列を使用します。一般に、配列は完全なバイナリ ツリーを表す場合にのみ適しています。完全なバイナリ ツリーでない場合、スペースが無駄になるためです。実際には、ストレージに配列を使用するのはヒープだけです。バイナリ ツリーの順次ストレージは、物理的には配列であり、論理的にはバイナリ ツリーです。
チェーンストレージ:
二分木の連結記憶構造とは、二分木を表現するために連結リストが使用されること、すなわち、要素の論理的関係を示すためにチェーンが使用されることを意味する。
通常の方法では、リンク リストの各ノードは、データ フィールドと左右のポインタ フィールドの 3 つのフィールドで構成されます。左ポインタと右ポインタは、左の子と右の子がポイントするリンクのストレージ アドレスを与えるために使用されます。ノードのそれぞれです。
鎖の構造は二本鎖と三本鎖に分かれます。
typedef int BTDataType;
// 二叉链
struct BinaryTreeNode
{
struct BinTreeNode* pLeft; // 指向当前节点左孩子
struct BinTreeNode* pRight; // 指向当前节点右孩子
BTDataType data; // 当前节点值域
}
// 三叉链
struct BinaryTreeNode
{
struct BinTreeNode* pParent; // 指向当前节点的双亲
struct BinTreeNode* pLeft; // 指向当前节点左孩子
struct BinTreeNode* pRight; // 指向当前节点右孩子
BTDataType data; // 当前节点值域
};