简体   繁体   English

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

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

could anyone tell me what is the simplest algorithm with use of recursion which would take a root of a so called binary tree (so called because it is not strictly speaking binary tree) and make every child in this tree connected with its sibling. 任何人都可以告诉我什么是使用递归的最简单的算法,它将采用所谓的二叉树的根(所谓的因为它严格来说不是二叉树)并使这个树中的每个孩子都与它的兄弟相连。
So if I have: 所以,如果我有:

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

then the sibling to 2 would be 3, to four five, to five six and to seven eight. 那么兄弟到2将是3,到4,5,到5和6到7。

Do a BFS, assign level numbers to nodes and connect nodes with the same level number. 执行BFS,为节点分配级别编号并使用相同级别编号连接节点。

Pseudocode: 伪代码:

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;
        }
    }
}

The peek() function gives the next element in the queue without removing it. peek()函数提供队列中的下一个元素而不删除它。

I wasn't sure what your question meant exactly. 我不确定你的问题究竟是什么意思。 But, I hope this conveys the idea. 但是,我希望这传达了这个想法。 You could tweak this to suit your needs. 您可以调整它以满足您的需求。

There's actually a rather elegant solution to this. 实际上这是一个相当优雅的解决方案。 One useful hint is the requirement that this be recursive. 一个有用的提示是要求递归。 When working on a tree, there are several ways to traverse the tree... essentially you can do dfs, or bfs. 在树上工作时,有几种方法可以遍历树...基本上你可以做dfs或bfs。 DFS is naturally recursive and so our solution likely involves dfs (recursive bfs is not at all natural). DFS是自然递归的,所以我们的解决方案可能涉及dfs(递归bfs一点也不自然)。 The next key thing is that in a left-to-right dfs, if we kept track of the last thing seen at each level, we could easily link to our siblings. 接下来的关键是,在从左到右的dfs中,如果我们跟踪每个级别上看到的最后一件事,我们可以轻松链接到我们的兄弟姐妹。 This (with a bit more simplification) leads to our solution: 这(稍微简化一点)导致我们的解决方案:

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