我正在尝试找到以下问题的有效解决方案。给定输入是:二进制树中的节点数,根,边和一些节点的列表,如果它是在网格中绘制的,则在树中找到它们的坐标,例如 边缘上的边或节点没有按任何特定顺序给出,但是将节点连接到左子节点的边在输入中出现得更早。树可以拥有超过百万个节点并使用
构建树class Node {
public Node left;
public Node right;
public int key;...}
太慢了。但我找不到如何以可以找到节点坐标的方式表示树。 输入示例:
4 0 // 4 is number of nodes, 0 is root
0 1 // edge
0 3 // edge
2 3 // edge
我应该找到节点的坐标,例如3
和输出将为:3 1
答案 0 :(得分:0)
您需要构建整个树,因为您需要知道树的结构才能确定X坐标。
但是,如果您的算法线性,即使有数百万个节点也不应该是一个问题。
算法看起来非常简单。
首先我们需要构建树结构。在构建树时,我会使用Map<Integer, Node>
来快速访问特定的Node
(该地图稍后也会有用)。(如果{{甚至Node[]
也可以正常工作1}} ids是范围Node
)中的整数
0..NodeCount-1
类应该有一个方便方法Node
,它首先添加addNode(Node node)
节点,然后添加left
节点。它看起来像这样:
right
关于void addNode(Node node) {
if (left == null)
left = node;
else
right = node;
}
方法,这样的事情应该起作用
addEdge(int from, int to)
然后,我们需要将X坐标分配给节点。我会使用递归函数,如下所示:
void addEdge(int from, int to) {
Node fromNode = nodes.get(from); // this should never be null, root should be added manually first
Node toNode = nodes.get(to);
if (toNode == null) {
toNode = new Node(to); // 'content' constructor
nodes.put(to, toNode);
}
fromNode.addNode(toNode);
}
并像这样称呼它
int assignXY(Node node, int lastX, int y) {
node.y = y;
node.x = 1 + (node.left == null ? lastX: assignX(node.left, lastX, y - 1));
return (node.right == null ? node.x : assignX(node.right, node.x, y - 1);
}
现在,所有节点都有X坐标,因此您只需从我们之前定义的assignXY(rootNode, -1, maxDepth);
中提取您感兴趣的Node
并返回其Map