これはばかげた質問のように思えるかもしれません。私は頻繁に混乱することを知っていますが、コードに執着するのをやめて、なぜそれを使用する必要があるかという本当の問題に集中できるように、コードを理解する必要があります。
したがって、コードでは、次のようないくつかの割り当てが表示されます。
struct bst_node** node = root;
node = &(*node)->left;
node = &(*node)->right;
is there an invisible parenthesis here?
node = &((*node)->right);
この例は、literateprograms.org から取得したものです。
だから私には &(*node) は不要なようで、代わりに node->left と書いた方がいいかもしれませんが、コードは私が理解できない場所で機能しているようで、それは私がそれらの行で何が起こっているのかを誤解しています。特に、「削除された」データを常にツリーの一番下に移動してノードを削除しているコードのある場所で、「物事を壊す」ことなくノードを安全に削除する必要があります。入手方法
old_node = *node;
if ((*node)->left == NULL) {
*node = (*node)->right;
free_node(old_node);
else if ((*node)->right == NULL) {
*node = (*node)->left;
free_node(old_node);
} else {
struct bst_node **pred = &(*node)->left;
while ((*pred)->right != NULL) {
pred = &(*pred)->right;
}
psudo-code: swap values of *pred and *node when the
bottom-right of the left tree of old_node has been found.
recursive call with pred;
}
ツリー構造をそのまま維持できます。これにより構造が完全であることを確認する方法がわかりません。何が起こっているのかを知っている人からの助けをいただければ幸いです。node は、関数呼び出しで作成されたスタック上のローカル変数であると解釈します。これはダブルポインターであるため、スタック内の場所を指します(関数呼び出しの前に &(*node) を実行したため、これを想定しています)、それ自体のスタックまたは前の関数のいずれかであり、そのノードを指しますヒープ上。
上記のサンプルコードでは、どちらかが NULL であるため、左または右のいずれかを切り替えてから、そうでない方を切り替えます (もう一方が NULL ではないと仮定しますか?) 私が言ったように、これがどのように機能するかはわかりません。私の質問は、主に &(*node) <=> ノードだと思うという事実に関連していますが、そうでないかどうかなどを知りたい.