簡體   English   中英

在偽二叉樹中為每個子節點設置兄弟節點

[英]Setting sibling for each child in a pseudo binary tree

任何人都可以告訴我什么是使用遞歸的最簡單的算法,它將采用所謂的二叉樹的根(所謂的因為它嚴格來說不是二叉樹)並使這個樹中的每個孩子都與它的兄弟相連。
所以,如果我有:

             1
           /   \  
          2     3  
         / \     \  
        4   5     6
       /           \
      7             8  

那么兄弟到2將是3,到4,5,到5和6到7。

執行BFS,為節點分配級別編號並使用相同級別編號連接節點。

偽代碼:

void connectSiblings(Node root)
{
    Queue q = new Queue();
    root.level = 1;
    q.enqueue(root)
    while(!q.isEmpty())
    {
        elem = q.dequeue();
        //add elem's children to q
        if (elem.left != NULL)
        {
            elem.left.level = elem.level + 1;
            q.enqueue(elem.left);
        }
        if (elem.right != NULL)
        {
            elem.right.level = elem.level + 1;
            q.enqueue(elem.right);
        }

        //check level numbers and assign siblings
        if (elem.level == q.peek().level)
        {
             elem.sibling = q.peek();
             q.peek().sibling = elem;
        }
    }
}

peek()函數提供隊列中的下一個元素而不刪除它。

我不確定你的問題究竟是什么意思。 但是,我希望這傳達了這個想法。 您可以調整它以滿足您的需求。

實際上這是一個相當優雅的解決方案。 一個有用的提示是要求遞歸。 在樹上工作時,有幾種方法可以遍歷樹...基本上你可以做dfs或bfs。 DFS是自然遞歸的,所以我們的解決方案可能涉及dfs(遞歸bfs一點也不自然)。 接下來的關鍵是,在從左到右的dfs中,如果我們跟蹤每個級別上看到的最后一件事,我們可以輕松鏈接到我們的兄弟姐妹。 這(稍微簡化一點)導致我們的解決方案:

void dfs_link(node* n, stack<node*>& st) {
  if (!n) return;
  if (!st.empty()) { st.top()->sibling = n; st.pop(); }
  dfs_link(n->left, st);
  dfs_link(n->right, st);
  st.push(n);
}

void link_tree(node* root) {
  stack<node*> st;
  dfs_link(root, st);
}

暫無
暫無

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

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