2017-04-11 50 views
1

考慮一個樹(無序的),其中所述節點通過n個標記爲0,與始終標記爲0重新排列用樹標籤

我希望構造一個單獨的樹,根節點,其中,每個非父 - 根節點m是其最近的祖先,標籤小於m。

例如,給定此樹:

(0 (1 (3)) (5 (7 (9 4) 2 (6))) 8)

所需的輸出是:

(0 (1 (3) 5 (7 (9))) 4 2 (6) 8)

注意,節點2具有比其父5在較小的標籤,所以其移動在樹上;節點4比它的父親7和它的祖父母5少,因此它向上移動到它的祖輩0。

幼稚的方法是獨立處理每個節點,遍歷向上,直到遇到較低的標籤。這將成爲如情況非常昂貴:

(0 (n (n-1 ... (2 (1)))))

感覺就像應該有處理這種重新安排一個相當簡單的子二次算法,但我不能制定正確的藥汁,甚至找到一個明顯的遍歷順序可以最大限度地減少冗餘處理的數量。這是一個定義明確的解決方案的常見問題嗎?

回答

1

該算法將是以下:

  1. 設定0作爲樹的根
  2. 原始樹執行DFS。
  3. 執行遞歸注入。

遞歸注入(節點,父):

  1. 如果節點比親本大,注入作爲母體的孩子。
  2. 否則遞歸注入(node,parent.parent)
+1

啊是的那就是那個!直截了當,看到它的作用微不足道。 也容易製作遞歸的迭代版本。 謝謝@xenteros。 – MorT

+1

@MorT沒有必要用迭代算法替換遞歸。您可以擁有相同的性能和更清晰的代碼。順便說一句,在[所以]我們upvote有用的答案,並addaly接受最好的一個:) – xenteros

+0

唉,這裏提出的問題是一個大型系統的廣泛修剪版。實際的實現不提供關於樹深度的任何保證,並且嵌入不適用於尾遞歸。 感謝您的禮儀小費;) – MorT