全文カタログ
序章
先ほど、二分木の基礎知識を紹介し、二分木の表現には逐次構造と連鎖構造の2つの構造があることを学びました。つまり、シーケンシャル リストまたはリンク リストを使用してバイナリ ツリーを表現します。
バイナリ ツリーの詳細な説明を参照してください。
前回の記事では、バイナリ ツリー (つまり、ヒープ) への逐次アクセスとそのインターフェイスの実装について学びました。
ヒープとインターフェイスの実装については、こちらをご覧ください。
この記事では二分木の連鎖アクセスを紹介しますが、連結リストのノードが二分木のノードに自由にアクセスすることは難しいため、連鎖二分木を使って追加することは実際には意味がありません。 、削除、確認、変更します。この記事では、バイナリ ツリー チェーン構造に関するいくつかのトピックを紹介します。単一値バイナリ ツリー、バイナリ ツリーの最大深さ、反転バイナリ ツリー、同一ツリーです。
連鎖二分木のノード構造により、優れた再帰特性を備えています。この記事では、次のことを説明するために再帰展開図を詳細に描きます。
typedef int BTDataType;
struct BinaryTreeNode
{
struct BinTreeNode* _pLeft; // 指向当前节点左孩子
struct BinTreeNode* _pRight; // 指向当前节点右孩子
BTDataType _data; // 当前节点值
}
単一値二分木
トピックの説明とアイデア
バイナリツリー内の値がすべて等しいかどうかを判断し、等しい場合は true を返し、そうでない場合は false を返す関数を実装する必要があります。
再帰することができます:
各再帰は、このノードとその左右の子ノードの値が等しいかどうかを判断し、等しい場合は次のレベルに true を返し、そうでない場合は false を返します。このノードが NULL の場合、このノードの
再帰行が終了し、行が上に上がる レベルは true を返します。
このノードは判断され、true の場合は下方向への再帰を継続し、それ以外の場合は直接 false を返します。
上位に戻る場合は、このノードの左右の子ノードがそれぞれtrueを返した場合のみtrueとなるので、その左右の子ノードが返した値の論理積をとった結果を返します。
達成
まずルートが NULL かどうかを判断し、NULL の場合は直接 true を返し、
このノードの値が左右の子の値と等しくない場合は直接 false を返し、
等しくなったらその左右の子を使用します。ノードをルート ノード root として、それぞれ再帰的に実行すると、返される値の論理 AND の結果が返されます。
bool isUnivalTree(struct TreeNode* root)
{
if (root == NULL)
{
return true;
}
if ((root->left && root->left->val != root->val)||(root->right && root->right->val != root->val))
{
return false;
}
else
{
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
}
再帰展開グラフ(関数コードが少し長いため、グラフ描画時に関数名と戻り値のみを記述します):
バイナリツリーの最大深さ
トピックの説明とアイデア
バイナリ ツリーの最大の深さを見つける関数を実装する必要があります。
ノードの左右のサブツリーの深さを再帰的に計算し、次に
左右のサブツリーの深さを比較し、大きい方の値 + 1 がノードの深さとなり、この値を上位に返します。レベル。
達成
この問題の実現は比較的簡単です。
まずノードが NULL かどうかを判断し、NULL の場合は直接 0 を返し、
次に左右のサブツリーの深さをそれぞれ計算して保存し、
最後に大きい方の左右のサブツリー + 1 の値を返します。
左右のサブツリーの深さを計算した後、結果を保存する必要があることに注意してください。保存しないと、効率が重大な影響を受けます。
int maxDepth(struct TreeNode* root)
{
if (root == NULL)
{
return 0;
}
int lefthigh = maxDepth(root->left);
int righthigh = maxDepth(root->right);
return lefthigh > righthigh ? lefthigh + 1 : righthigh + 1;
}
再帰展開図(NULL判定部分を省略):
二分木を反転する
トピックの説明とアイデア
二分木の左右のノードの反転を実現する関数を実装する必要があります。
バイナリ ツリーの各ノードには、このノードの値と 2 つの子ノードのポインタが含まれていることがわかっているため、各ノードの左右の子ノードのポインタを再帰的に交換するだけで済みます。
達成
まずこのノードが NULL かどうかを判断し、空の場合は NULL を返し、
次に 2 つの子ノードのポインタを交換し、
次に左右の子ノードをパラメータとして再帰し、
最後にこのノードのポインタを上位レベルに返します。
struct TreeNode* invertTree(struct TreeNode* root)
{
if (root == NULL)
{
return NULL;
}
struct TreNode* temp = root->left;
root->left = root->right;
root->right = temp;
invertTree(root->left);
invertTree(root->right);
return root;
}
再帰的展開図:
同じ木
トピックの説明とアイデア
2 つのバイナリ ツリーが同じかどうかを判断し、等しい場合は true を返し、そうでない場合は false を返す関数を実装する必要があります。
各ノード自体がその左右の子ノードと等しいかどうかを再帰的に判断できます。
判断するときは、ノードの値が等しいかどうかのみ判断できます。
ノードが等しい場合は、下方向に再帰し、左右の子ノードを返します。値の論理積の結果。
達成
最初に p と q が空かどうかを判断し、両方が空の場合は true を返し、
すべてが空ではなくいずれか 1 つが空である場合は、等しくないことを意味し、false を返します。その後、
値が正しいかどうかを判断します。このノードの が等しい場合、等しくない場合は false を返し、
等しい場合は、2 つのツリーの左側と右側のノードをそれぞれ再帰し、それらの戻り値の論理 AND の結果を返します。
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if (p == NULL && q == NULL)
{
return true;
}
else if (p == NULL || q == NULL)
{
return false;
}
if(p->val!=q->val)
{
return false;
}
else
{
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
}
再帰展開図(判定部分省略):
要約する
この時点で、連鎖バイナリ ツリーに関する OJ 演習がいくつか紹介されています。
この部分を明確に紹介していない、またはこの部分に問題があると思われる場合は、コメント欄に指摘してください。
この記事が少しでもお役に立てましたら、ワンクリックでつながれば幸いです
皆さんと一緒に進歩していきたいと思っています