1. 程式人生 > >演算法導論13章紅黑樹 思考題總結

演算法導論13章紅黑樹 思考題總結

13-1 (持久動態集合) 有時在演算法的執行過程中我們會發現在更新一個動態集合時,需要維護其過去的版本。我們稱這樣的集合為持久的(persistent)。實現持久集合的一種方法是每當改集合被修改時,就將其完整地複製下來,但是這種方法會降低一個程式的執行速度,而且佔用過多的空間。有時候,我們可以做得更好些。

       考慮一個有 INSERT、DELETE和SEARCH操作的持久集合 S,我們使用如圖13-8(a)所示的二叉搜尋樹來實現。對集合的每一個版本都維護一個不同的根。為了將關鍵字 5 插入到集合中,建立一個具有關鍵字 5 的新結點。該結點成為具有關鍵字 7 的新結點的左孩子,因為我們不能更改具有關鍵字 7 的已存在結點。類似地,具有關鍵字 7 的新結點成為具有關鍵字 8 的新結點的左孩子,後者的右孩子成為具有關鍵字 10 的已存在結點。關鍵字為 8 的新結點又成為關鍵字為 4 的新根結點 r' 的右孩子,而 r' 的左孩子是關鍵字為 3 的已存在結點。這樣,我們只是複製了樹的一部分,新樹共享了原樹的一些結點,如圖13-8(b)所示。

        假設樹中每個結點都有屬性 key、left 和 right,但沒有屬性parent。

a. 對於一課一般的持久二叉搜尋樹,為插入一個關鍵字 k 或刪除一個結點 y,需要改變那些結點。

ANSWER:

插入:需要修改插入路徑上的每一個結點。

刪除:① 若 z 有不多於一個兒子,則 z 的所有祖先都需要修改。

           ② 若 z 有兩個兒子,則 z 的後繼 y 會移動到 z 的位置,所以 y 和 z 的祖先均需修改。(特別地,若 z 是 y 的祖先,上面的說法也成立。)

b.請寫出一個過程 PERSISTENT-TREE-INSERT,使得在給定一棵持久樹 T 和一個要插入的關鍵字 k 時,它返回將 k 插入 T 後得到的新的持久樹 T'。

ANSWER:

<span style="font-size:18px;">虛擬碼
PERSISTENT-TREE-INSERT(root, k):
    if root == NIL:
        newr = make-new-node(k)
    else:
        newr = copy-node(root)
        if k.key < z.key:
            newr.left = make-new-node(newr.left, k)
        else:
            newr.right = make-new-node(newr.right, k)
    return newr</span>
c. 如果持久二叉搜尋樹 T 的高度為 h,實現 PERSISTENT-TREE-INSERT 過程的時間和空間需求分別是多少?(空間需求與新分配的結點數成正比。)

ANSWER:時間和空間均為 O(h) 複雜度。

d. 假設在每個結點中增加一個父結點屬性。這種情況下,PERSISTENT-TREE-INSERT 需要做一些額外的複製工作。證明:PERSISTENT-TREE-INSERT 的時間需求和空間需求為 Ω(n),其中 n 為樹中的結點個數。

AMSWER:因為插入過程,形成了新的根結點,所以根結點的子結點需指向新的父結點;然後對根結點的子樹遞迴,亦然。所以需要對 n 個結點進行修改,所以時間和空間均為 Ω(n)。