演算法導論14.3區間樹 練習總結
14.3-1 寫出作用於區間樹的結點且在 O(1) 時間內更新 max 屬性的過程 LEFT-ROTATE 的虛擬碼。
ANSWER:
虛擬碼:
LEFT-ROTATE(T, x)
y = x.right
y.max = x.max
x.max = max(x.left.max, y.left.max, x.int.high)</span></span>
14.3-2 改寫 INTERVAL-SEARCH 的程式碼,使得當所有區間都是開區間是,它也能正確地工作。
ANSWER:將第 3 行的 x.left.max ≥ i.low 改為 x.left.max > i.low。
14.3-3 請給出一個有效的演算法,對一個給定的區間 i,返回一個與 i 重疊且具有最小低端點的區間;或者當這樣的區間不存在時返回 T.nil。
ANSWER:
虛擬碼: MIN-SEARCH(T, i) x = T.root res = T.nil mark = INT_MAX while x != T.nil if i overlap x.int if x.int.low < mark mark = x.low res = x if x.left != T.nil and x.left.max ≥ i.low x = x.left else x = x.right return res</span>
14.3-4 給定一棵區間樹 T 和一個區間 i,試描述如何在 O(min(n,klgn)) 時間內列出 T 中所有與 i 重疊的區間,其中 k 為輸出的區間數。(提示:一種簡單的方法是做若干次查詢,並且在這些查詢操作中修改書,另一種略為複雜點的方法是不對樹進行修改。)
ANSWER:類似於前序遍歷,但時間仍為 O(min(n,klgn))。
虛擬碼: SEARCH-ALL(T.root, i) x = T.root if i overlap x.int print x if x.left != T.nil and x.left.max ≥ i.max SEARCH-ALL(x.left, i) if x.right != T.nil and x.right.int.low ≤ i.high and x.right.max ≥ i.low SEARCH-ALL(x.right, i)</span>
14.3-5 對區間樹 T 和一個區間 i,請修改有關區間樹的過程來支援新的操作 INTERVAL-SEARCH-EXACTLY(T, i),它返回一個指向 T 中結點 x 的指標,使得 x.int.low = i.low 且 x.int.high = i.high;或者,如果 T 不包含這樣的區間時返回 T.nil。所有的操作(包含 INTERVAL-SEARCH-EXACTLY)對於包含 n 個結點的區間樹的執行時間都應為 O(lgn)。
ANSWER:直接按照 i.low 搜尋二叉樹,然後判斷 x.int.high 是否等於 i.high 即可。
14.3-6 說明如何來維護一個支援操作 MIN-GAP 的一些數的動態集 Q,使得該操作能給出 Q 中兩個最接近的數之間的差值。例如,Q = {1, 5, 9, 15, 18, 22},則 MIN-GAP 返回 18 -15 = 3,因為 15 和 18 是 Q 中兩個最接近的數。要使得操作 INSERT、DELETE、SEARCH 和 MIN-GAP 儘可能高效,並分析它們的執行時間。
ANSWER:給紅黑樹的每個結點新增 min、max、mingap 屬性。
x.min(以 x 為根的樹中最小的關鍵字。):插入時,只需更新插入的結點至根結點路徑上 O(lgn) 個結點。更新結點操作 x.min = min(x.left.min, x.key) 只需 O(1) 時間,所以插入操作對更新 min 屬性也是 O(lgn) 時間。刪除同理。
x.max(以 x 為根的樹中最大的關鍵字。):插入、刪除和 x.min 類似。x.max = max(x.right.max, x.key)。
x.mingap(以 x 為根的樹的 MIN-GAP):插入、刪除依然是 O(lgn) 時間更新 mingap 屬性,x.mingap = min(x.left.mingap, x.right.mingap, x.key - x.left.max, x.right.min - x.key)。
綜上,INSERT、DELETE、SEARCH 時間為 O(lgn),MIN-GAP 時間為 O(1)。