木に関連する再帰関数を書くのに苦労しています。これらの機能は一般的ではなく、試験環境でGoogleを使用できないため、これらの機能にGoogleを使用することはできません。
再帰関数のアルゴリズム/擬似コードの記述を成功させるための「トリック」はありますか?これについて私が考えるべき/それに近づくべき特定の方法はありますか?
例:与えられたバイナリツリーが有効なAVLツリーと一致する構造を持つかどうかを決定する再帰関数を記述します。
予想されるソリューション:
template <typename Type>
bool is_avl (const Binary_node<Type> * tree) {
if (tree == NULL) {
return true;
}
return is_bst (tree)
&& is_avl (tree->left())
&& is_avl (tree->right())
&& std::abs(height(tree->left()) - height(tree->right())) <= 1;
}
あなたは運がいい!あり(ソート)です!
あなたがよくしたいことは、2/3のケースを特定することです:
あれは:
例を考えてみてください(バイナリ検索ツリー上のDFS):
bool DFS(Node currentNode, T searchValue)
{
// base case
if (currentNode.Value == searchValue)
return true;
// recursive case and exit case
if (curentNode.Left != null && DFS(currentNode.Left, searchValue))
return true;
// recursive case and exit case
if (curentNode.Right != null && DFS(currentNode.Right, searchValue))
return true;
return false;
}
だからここにあります:
それでは、同じツリーの順序通りのトラバースについて考えてみましょう。
体内トラバーサルの場合は次のようになります。
void InOrder (Node currentNode)
{
// 3
if (currentNode == null)
return;
// 2
InOrder(currentNode.Left);
// 1
print(currentNode.Value);
// 2
InOrder(currentNode.Right);
}
ほとんどすべての再帰関数にはこれらの要素があります。それらを識別し、正しい順序にすることが重要です。
アルゴリズム/再帰関数の擬似コードの作成を成功させるための「トリック」はありますか?
絶対に!再帰関数を作成するときは、特定のデータ構造で実行している帰納法を明示的に説明しています。したがって、関数を作成するときの「トリック」は2つあります。
たとえば、ツリー内のすべてのノードをカウントする再帰関数は次のとおりです。
def TreeCount(Tree):
if Tree.isLeaf: # we can't go down any further
return 1
else: # break the problem into sub-problems we can solve with this function
return 1 + TreeCount(Tree.left) + TreeCount(Tree.right)
ご覧のように、私が見ているツリーのタイプ(リーフとノード)で関数を分割し、ノードを扱っている場合は、サブツリーの再帰の観点から処理しました。