簡體   English   中英

樹木分割(提取)算法

[英]Tree splitting(extracting) algorithm

在最簡單的情況下,我有兩棵樹(有向圖),每個樹節點都有一個唯一的ID,並且可以有多個子代,其中第二棵樹的所有葉子都包含在第一棵樹的葉子中。 基於葉子,我想將第一棵樹分成兩棵樹,這樣新的第一棵樹將不包含原始第二棵樹的任何葉子,而新的第二棵樹將包含原始第二棵樹的所有葉子。 訣竅還在於,如果節點的所有子代都將移至新的第二棵樹,則節點本身也應移至該位置。

例如,將這兩個樹作為輸入:

  • 1(第一棵樹的根)
    • 11
      • 111
        • 1111
          • 11111
          • 11112
        • 1112
          • 11121
          • 11122
      • 112
        • 11201
        • 11202
    • 12
      • 121
        • 12101
        • 12102
      • 122
        • 12201
        • 12202
  • 2(第二棵樹的根)
    • 21
      • 211
        • 2111
          • 11112
      • 212
        • 11201
        • 11202

結果,我想得到兩棵新樹:

  • 1(新的第一棵樹的根)
    • 11
      • 111
        • 1111
          • 11111
        • 1112
          • 11121
          • 11122
    • 12
      • 121
        • 12101
        • 12102
      • 122
        • 12201
        • 12202
  • 2(新第二棵樹的根)
    • 21
      • 211
        • 2111
          • 11112
      • 112(從原始第一棵樹復制的節點會導致其所有子節點都被復制)
        • 11201
        • 11202

實現這一目標的最佳方法(算法)是什么?

從第一棵樹中刪除節點很簡單,但是我有一個問題,如何在合適的地方從第一棵樹構造第二棵樹重用節點。

我正在嘗試在Java版本1.7中實現此拆分(我不能使用1.8)。

編輯

我能夠提出一種解決方案,下面的答案中有更多詳細信息,但是如果有人會提供更好的解決方案,我也會很高興的:)

我想出了解決我的問題的方法,也許對任何人都有用。 我的算法如下:

  1. 讓我們將第一棵原始樹稱為源樹,第二棵原始樹稱為掩碼樹。
  2. 將所有原始樹及其父級的樹轉換成葉子列表。
  3. 遍歷葉子列表,並從葉子親本重建樹。
    • 來自掩碼樹的父母具有更高的優先級,而來自源樹的父母具有更高的優先級
    • 對於掩碼樹的父級,將源樹的父級注冊為可能的替代項
  4. 遍歷可能的替換,如果替換未在任何樹中使用,則將其替換為節點。

不知道我是否說得足夠清楚。 如果沒有,請檢查BitBucket TreeSplitter上可用的浸漬

該解決方案可能不是最佳解決方案,因此,如果您有更好的方法,可以將其發布為答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM