記事ディレクトリ
序章
現在北京時間2023年6月7日15時28分、ちょうど授業の期末試験を終えたところなので、寮に戻ったらすぐにこのブログを公開する予定です。今週のレビュー指標を完了するには、あと 2 つのブログが必要です。来て!
1. 木の概念
ツリーは非線形データ構造であり、n (n>=0) 個の有限ノードで構成される一連の階層関係です。根が上を向き、葉が下を向いている、逆さまの木に見えることからツリーと呼ばれています。ツリーはルートとサブツリーの 2 つの部分に大別できます。ルート ノードはツリーの最も特殊なノードであり、先行ノードがありません。ルート ノードを除く他のノードは M (M>0) 個の素集合 T1、T2、...、Tm に分割され、各集合 Ti (1<= i<= m) は構造とツリー状のサブツリーです。各サブツリーのルート ノードには先行ノードが 1 つだけあり、0 個以上の後続ノードを持つことができます。したがって、ツリーは再帰的に定義できます。
注:サブツリー間に交差があってはなりません。交差しないと、ツリー構造ではなくグラフ構造になります。
1.1. ツリーのその他の関連概念
ノードの次数:ノードに含まれるサブツリーの数は、上の図に示すように、ノードの次数と呼ばれます: A は 6 リーフ ノード
または終端ノードです:次数 0 のノードはリーフと呼ばれますノード; 上の図に示すように: B、C、H、I... などのノードは葉ノード、
非終端ノード、または分岐ノードです:次数が 0 でないノード; 上の図に示すように: などのノードD、E、F、G... はブランチ ノードであるため
親ノードまたは親ノード (重要): 1 つの場合 ノードに子ノードが含まれる場合、上の図に示すように、このノードはその子ノードの親ノードと呼ばれます。 : A は B の親ノードです 子ノード
または子ノード (重要):ノードに含まれるサブツリーのルート ノードはノードの子ノードと呼ばれます; 上の図に示すように: B は Bの子ノードですA.
兄弟ノード:同じ親ノードを持つノードは兄弟ノードと呼ばれます。 はツリーの次数です。上の図に示すように、ツリーの次数は 6 です。よく聞くバイナリ ツリーは、次数 2 のツリー ノードのレベルです。ルートの定義から始まり、ルートが第 1 レベル、ルートの子ノードが第 2 レベル、というようになります。ツリーの高さまたは深さ (重要):ツリー内のノードの最大レベル (上の図に示すように):ツリーの高さは 4いとこノード:親が同じレベルにあるノードはいとこです。上の図: H と I は兄弟ノードです。ノードが通過するブランチ上のすべてのノード。上の図に示すように: A はすべてのノード (知識) の祖先と子孫です: a をルートとするサブツリー内の任意のノード特定のノードをノードの子孫と呼びます。上に示すように、すべてのノードはフォレストの子孫です。
m (m>0) 個の素な木の集合をフォレストと呼び、たとえば和集合検索のデータ構造はフォレストで構成されます。
2. ツリーのコード実装の構造
ツリーの基本概念は前に紹介しました。コードでツリーを実装する方法を見てみましょう。
//这样结构定义树可以吗?
struct TreeNode
{
struct TreeNode* child1;
struct TreeNode* child2;
struct TreeNode* child3;
//...
int data;
};
答えは「いいえ」です。ツリーの次数を使用して、定義すべき子の最大数を明確に規定していないからです。したがって、この構造は間違っています。以下に構造を示します。ツリーの次数が N であると仮定し、次のコードを参照してください。
#define N 5
//假设N为5
struct TreeNode
{
struct TreeNode* ChildrenArr[N];
int data;
};
以下に、非常に強力な表現構造、左の兄弟と右の子の表現を紹介します。つまり、ツリー ノードには、最初の子ノードと次の兄弟ノードをそれぞれ指すポインターが 2 つだけあります。この表現はすべてのツリー構造を構築できます。
typedef int DataType;
struct TreeNode
{
struct TreeNode* _firstChild1; // 第一个孩子结点
struct TreeNode* _pNextBrother; // 指向其下一个兄弟结点
DataType _data; // 结点中的数据域
};
この表現方法では、各ノードの左の子と右の兄弟を直接見つけることができるため、記憶領域を節約でき、ツリー構造の走査効率も向上します。
2.1. ツリー構造の適用
通常、オペレーティング システムのディスク ファイル構造は古典的なツリー構造です。ここでは Linux システムを例に挙げます。
ディスク ファイル システムとしてツリー構造を使用する理由 Linux システムのディスク ファイル構造はツリー構造を採用しており、ユーザーに明確、シンプル、便利、効率的なファイル管理方法を提供します。
3. 二分木の概念
二分木は実際には次数 2 の木です。通常は以下のような状況が考えられます。
二分木では、次数 0 のノードは次数 2 のノードよりも常に 1 つ多く存在します。以下に、この結論を検証するための 2 つの簡単なシナリオを簡単に引用します。
3.1. 特殊な二分木の概念
3.1.1. 完全なバイナリツリー
深さが k の二分木の場合、そのすべてのノードが最初から k 番目の層にあり、すべての葉ノードが k 番目の層または k-1 番目の層にあり、k 番目の層の順序が左から右に連続している必要がある場合の場合、この二分木は完全な二分木になります。完全なバイナリ ツリーは、特別な種類の完全なバイナリ ツリーです。
では、高さ h の完全な二分木のノード数の範囲を見つけるにはどうすればよいでしょうか?
同様に、完全な二分木の高さの範囲は、(Sn) + 1 の対数、または (Sn+1) の底が 2 の対数であると推測できます。
3.1.2. 完全なバイナリツリー
各層のノード数が最大値に達すると、バイナリ ツリーは完全なバイナリ ツリーになります。つまり
、二分木の層の数が h で、ノードの総数が 2 の h 乗-1 であれば、それは完全な二分木になります。
完全なバイナリ ツリー内のノードの総数が 2 の h 乗 -1 になるのはなぜですか? 以下に私の分析を見てみましょう。
完全な二分木の要約点は算術差分式であることがわかりますが、もちろん、結論は完全な二分木の要約点の数は 2 の h 乗 -1 です。同様に、完全な二分木の高さは、2 に基づく h = log (Sn+1) の対数に等しくなります。
3.2. 二分木試験問題の解説
3.2.1. 質問 1
この質問は主に、バイナリ ツリーの基本的な特性の理解を評価します。つまり、バイナリ ツリー内の次数 0 のノードの数は、次数 2 のノードの数よりも常に 1 多くなります。この質問では B を選択してください。 。
3.2.2. 質問 2
実際、この質問の鍵は完全な二分木です。ここで、次数 1 の完全な二分木によれば、ノードは 1 または 0 のみです。この条件によれば、次数 0 の二分木は、次数 0 のノードよりも常に 1 つ多いノードを持ちます。 2. 次数 1 のノードが 1 つ、つまりリーフ ノード n0=2n/2=n であると推測できます。この質問には A を選択してください。
3.2.3. 質問 3
この質問は、完全なバイナリ ツリーの概念の理解をまだテストしています。まず第一に、完全な二分木のノードが Sn=n0+n0-1+n1 であることを知る必要があります。Sn=767 によると、n0 と n1 は整数でなければならないため、n1 = 0 となります。したがって、2n0 = 768、n0 は 384 に等しくなります。この質問では B を選択してください。
4. バイナリツリーの記憶構造
二分木の記憶構造は、チェーン構造二分木とシーケンス構造二分木の2種類に分けられます。その基礎となる実装は、リンク リストとシーケンシャル リストに対応します。
4.1. シーケンシャル構造のストレージ
シーケンシャル構造のバイナリ ツリーは、実際には配列を使用してデータを管理しています。一般に、完全でないバイナリ ツリーはスペースを無駄にするため、完全なバイナリ ツリーにのみ適しています。実際には配列を格納するのはヒープだけですが、ヒープについては後ほど説明します。バイナリ ツリー順次ストレージは、物理的には配列であり、論理的にはバイナリ ツリーです。
配列を使用したバイナリ ツリーの保存には制限があります。これは、完全なバイナリ ツリーの保存にのみ適しているためです。
4.2. チェーン構造のストレージ
二分木の連結記憶構造とは、二分木を表現するために連結リストが使用されること、すなわち、要素の論理的関係を示すためにリンクが使用されることを意味する。通常の方法では、リンク リストの各ノードは、データ フィールドと左右のポインタ フィールドの 3 つのフィールドで構成され、左右のポインタは、左の子と左の子がポイントするリンクのストレージ アドレスを与えるために使用されます。ノードの右の子が見つかります。鎖の構造は二元鎖と三重鎖に分かれますが、現在研究されているのは二元鎖で、有名な赤黒の木は三重鎖です。