赤黒木の回転:y = x.right; x.right = y.left。y.left.p = xをx.right.p = xと書くことは同じですか


8

CLRSでは、著者は以下の疑似コードによって赤黒ツリーの回転操作を紹介します。 左回転

LEFT-ROTATE(T, x)

    y = x.right        # Line 1
    x.right = y.left   # Line 2
    if y.left ≠ T.nil  # Line 3
        y.left.p = x   # Line 4
    y.p = x.p
    if x.p == T.nil
        T.root = y
    elseif x == x.p.left
        x.p.left = y
    else x.p.right = y
    y.left = x
    x.p = y

ここで、属性.left、.right、.pは、その左、右の子、およびその親に対応します。Tはツリーです。

私の主な質問は3行目と4行目です。

  1. 3行目のif条件が必要なのはなぜですか?この本には、NILは実際には赤黒の木の葉であると書かれているので、NILには親ポインターもあると思います。これらのコードはLine 3がなくても機能するはずです。

  2. Line 1とLine 2では、Line 4を次のように書くことができx.right.p = xますか?それらが実際に同じである場合、著者がそれを次のように書くことを選択した理由はありy.left.p = xますか?

私の本能はとx.right.p = xは異なりy.left.p = xます。しかし、これについての良い説明はありません。私はポインタの定義をチェックアウトしましたが、たくさんググった後でそれはまだかなり混乱しています...

回答:


3

ここに画像の説明を入力してください

注:わかりやすくするために、すべての図に親関係矢印を配置しませんでした。

図に示すように、nullノードは親を持つことができません。ここにもっと詳しい説明があります

  1. 図が示すように、3行目のチェックは、y.left決してnullでなければ必要ありません。これが保証されていない場合、このチェックは「nullポインター逆参照」エラーを防ぐためのものです。

  2. 使用の選択y.left.p = xはユーザーの好みです。私には、それははるかに明確です。私たちは作ります"y left subtree into x right subtree"

@HolderRoyが示した例はy.left機能しますが、ポインタを格納するための追加の割り当てが行われます(foreach関数呼び出し)。


nullノードに親ポインターがない理由はありますか?このセクションの本をもう一度チェックします。ただし、このプロパティはまったく取り上げられていません。
cindy50633

1
@ cindy50633 nullは、変数/プロパティが初期化されたことを示しますが、それが指すアドレスがないため、構造またはプロパティはありません。プロパティを保持する構造がparent存在しないため、parent存在しません。
mr.vea

2

説明の最後の行を読んだ後、ポインタを学んでいないことに気付いたので、何かがT.nilであるかどうかを判断する必要がある理由を理解するのは難しいかもしれません。しかし、私はまだあなたの質問に答えようとします、私はそれを明確に説明できればいいのですが。

  1. データ構造に関しては、確かに3行目は必要ありません。いずれにしても、y.left.pを調整する必要があります。

    ただし、特定の言語では、例としてC / C ++を使用するだけです。リーフとルートの親にはNULLまたはnullptrを使用します。つまり、何もないことを意味します。考えてみると、無駄な葉を節約するためにツリーノードと同じだけのメモリを費やす必要があるのでしょうか。もちろん違います。したがって、これをNULLポインターとしてマークします。これは、何も意味せず、また、pも左にも右にもありません。

    結論は、3行目でT.nilを判断すべきかどうかは実装に依存するということです。

  2. はい、できます。の後x.right = y.left、x.rightとy.leftは一時的に同じものになるため、x.right.pとy.left.pはまったく同じです。

    2〜4行目では、次のように書くこともできます:

beta = y.left;
x.right = beta; 
if beta != T.nil
    beta.p = x;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.