简体   繁体   English

表示为二叉树的 N 叉树的直径

[英]Diameter of an N-ary Tree represented as a Binary Tree

I need to compute the diameter of an N-ary tree represented as a Binary Tree (left-child, right-sibling representation).我需要计算表示为二叉树(左子、右兄弟表示)的 N 叉树的直径。 Can someone give me an idea or a pseudocode?有人可以给我一个想法或伪代码吗?

My best attempt was to add a +1 to the result whenever there was a left child, but I do not think that this is enough.我最好的尝试是在有左孩子时为结果添加 +1,但我认为这还不够。

The idea is to traverse the tree in a post-order traversal, collecting two pieces of information about each node:这个想法是在后序遍历中遍历树,收集关于每个节点的两条信息:

  • Its height它的高度
  • Its diameter它的直径

When this information is known for each of the children of a given node, then you can find out which are the two subtrees with the greatest heights.当已知给定节点的每个子节点的此信息时,您就可以找出高度最大的两棵子树。 The sum of these two heights represents a candidate for a diameter for the current node.这两个高度的总和表示当前节点的候选直径。 It should be compared with the diameters retrieved for each of the children.它应该与为每个孩子检索的直径进行比较。 The greatest of these all is the diameter of the current node.其中最大的是当前节点的直径。

And so the diameter can bubble up out of recursion.因此直径可以从递归中冒出来。

Here is an (runnable) implementation in JavaScript that executes the process on this example n-ary tree:这是 JavaScript 中的一个(可运行的)实现,它在此示例 n 叉树上执行该过程:

                _ _0_
               / / | \
              1 2 11  12
               / \   
              3   8 
             /|\  |
            4 5 7 9
             /   / 
            6  10

Note that the longest path in this tree connects node 6 with node 10, giving a path length of 6, which is the diameter of the whole tree.请注意,这棵树中最长的路径连接节点 6 和节点 10,路径长度为 6,这是整棵树的直径。

If we picture the data structure , not with the above edges, but with its links to nodes, then it looks like this (downward arrows = firstChild ; rightward arrows = nextSibling ):如果我们描绘数据结构,不是用上面的边,而是用它到节点的链接,那么它看起来像这样(向下箭头 = firstChild ;向右箭头 = nextSibling ):

          0
          ↓
          1 → 2  →  11  →  12
              ↓  
              3  →   8 
              ↓      ↓
              4→5→7  9
                ↓    ↓ 
                6    10

Here is an implementation to solve the problem with that data structure:这是解决该数据结构问题的实现:

 class Node { constructor(value, firstChild=null, nextSibling=null) { this.value = value; this.firstChild = firstChild; this.nextSibling = nextSibling; } getInfo() { let greatestHeight = 0; let secondGreatestHeight = 0; let greatestDiameter = 0; for (let child = this.firstChild; child; child = child.nextSibling) { let [height, diameter] = child.getInfo(); height++; if (height > greatestHeight) { secondGreatestHeight = greatestHeight; greatestHeight = height; } else if (height > secondGreatestHeight) { secondGreatestHeight = height; } if (diameter > greatestDiameter) { greatestDiameter = diameter; } } const diameter = greatestHeight + secondGreatestHeight; if (diameter > greatestDiameter) { greatestDiameter = diameter; } return [greatestHeight, greatestDiameter]; } getDiameter() { const [height, diameter] = this.getInfo(); return diameter; // We don't need the height anymore } } // Create the example tree: const tree = new Node(0, new Node(1, null, new Node(2, new Node(3, new Node(4, null, new Node(5, new Node(6), new Node(7))), new Node(8, new Node(9, new Node(10)))), new Node(11, null, new Node(12))))); // Print the diameter: console.log("diameter:", tree.getDiameter());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM