在伪二叉树中为每个子节点设置兄弟节点

时间:2012-02-04 16:20:21

标签: c++ binary-tree

任何人都可以告诉我什么是使用递归的最简单的算法,它将采用所谓的二叉树的根(所谓的因为它严格来说不是二叉树)并使这个树中的每个孩子都与它的兄弟相连。
如果我有:

             1
           /   \  
          2     3  
         / \     \  
        4   5     6
       /           \
      7             8  
然后兄弟到2将是3,到4,5到5和6到7。

2 个答案:

答案 0 :(得分:2)

执行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()函数给出队列中的下一个元素而不删除它。

我不确定你的问题究竟是什么意思。但是,我希望这传达了这个想法。您可以调整它以满足您的需求。

答案 1 :(得分:0)

实际上这是一个相当优雅的解决方案。一个有用的提示是要求递归。在树上工作时,有几种方法可以遍历树...基本上你可以做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);
}