Java 打印二叉树的所有可能直径?

Java 打印二叉树的所有可能直径?,java,data-structures,binary-tree,Java,Data Structures,Binary Tree,我知道如何计算树的直径,但我想打印所有可能的树直径。以以下为例:- 1 / \ 2 3 / / \ 4 5 6 上述树木的所有可能直径为:- 任何关于方法的帮助都会非常有用。我想你指的是从一片叶子到另一片叶子的所有可能的最大长度路径 递归可能是您的最佳选择-在伪代码中,例如: path(startNode, endNode) { if startNode = endNode return; for each p

我知道如何计算树的直径,但我想打印所有可能的树直径。以以下为例:-

        1
       / \
      2   3
     /   / \
    4   5   6
上述树木的所有可能直径为:-


任何关于方法的帮助都会非常有用。

我想你指的是从一片叶子到另一片叶子的所有可能的最大长度路径

递归可能是您的最佳选择-在伪代码中,例如:

path(startNode, endNode) {
  if startNode = endNode return;
  for each possible next node n {
    add n to your path;
    path(n, endNode);
  }
}

您可以为每对叶调用此函数,然后丢弃任何非最大长度路径,或者选择以更聪明的方式调用此函数的叶,我将留给您在图形中如何执行此操作:

从任意节点n运行BFS以查找距离该节点n'最近的节点 将BFS从节点n'运行到其最远的节点n 从n'到n的路径是树的直径 因此,看看一棵可以展开成图形的树:

直径路径从左子树最低层上的任何叶子到右子树最低层上的任何叶子

现在,因为你不知道哪两个节点是直径的末端节点,而且你只有父子链接,所以上述算法本身就不起作用。但是,您可以使用这个类比来构建一个在树上而不是在图形上工作的模型

好的,这里有一些快速代码,你可以使用它可能不是最佳的,但它的工作

public class BinarySearchTree {
    ...

    public Iterable<T> diameter() {
        if (this.root == null) {
            return null;
        }

        Deque<T> diameterLeftPart = new ArrayDeque<T>();
        Deque<T> diameterRightPart = new ArrayDeque<T>();

        diameter(this.root.left, diameterLeftPart);
        diameter(this.root.right, diameterRightPart);

        Deque<T> diameter = new ArrayDeque<T>();

        for (Iterator<T> it = diameterLeftPart.iterator(); it.hasNext();) {
            diameter.offerLast(it.next());
        }

        diameter.offerLast(this.root.item);

        for (Iterator<T> it = diameterRightPart.descendingIterator(); it.hasNext();) {
            diameter.offerLast(it.next());
        }

        return diameter;
    }

    private void diameter(Node node, Deque<T> diameter) {
        if (node == null)  {
            return;
        }

        Deque<T> leftPart = new ArrayDeque<T>();
        Deque<T> rightPart = new ArrayDeque<T>();

        diameter(node.left, leftPart);
        diameter(node.right, rightPart);

        if (leftPart.size() > rightPart.size()) {
            diameter.addAll(leftPart);
        } else {
            diameter.addAll(rightPart);
        }

        diameter.offerLast(node.item);
    }

    ...
}
快速解释:

我们知道根是直径路径的组成部分。 所以,我们想要得到左子树中的最长路径和右子树中的最长路径。 它们粘在一起,形成一个直径

使用递归调用diameternode.left、leftPart和diameternode.right、rightPart、leftPart和rightPart分别在左、右子树中包含最长路径

简单地比较它们的大小,我们就可以知道我们将使用哪一个来构建树上一层的直径

总而言之:
递归首先向下到树,返回该子树中最长的路径,向上传递到其父树,一直传递到根。

给定的直径是给定树的单个数字,你所说的所有可能的直径是什么意思?你得到了直径5,因为实际直径是5。从来没有听说过树数据结构有直径。5是树的深度。我可能会尝试一种路径查找算法不,深度是3here@weston我的意思是打印该区域的所有节点!!!首先,这不是家庭作业。“遥远”在这里意味着什么。我想你说的是最深的节点?我已经编辑了我的答案。当前版本只返回1个直径,但它可以让您了解如何沿着树移动:在前面的评论中,它只返回N个可能的最长直径中的1个,但最长的直径始终是树中最大的路径。它可以不止一个,但长度应该相等。!!!在代码中,如何计算直径!!!如何查找开始节点和结束节点。。。因为我们只知道树根。
public class BinarySearchTree {
    ...

    public Iterable<T> diameter() {
        if (this.root == null) {
            return null;
        }

        Deque<T> diameterLeftPart = new ArrayDeque<T>();
        Deque<T> diameterRightPart = new ArrayDeque<T>();

        diameter(this.root.left, diameterLeftPart);
        diameter(this.root.right, diameterRightPart);

        Deque<T> diameter = new ArrayDeque<T>();

        for (Iterator<T> it = diameterLeftPart.iterator(); it.hasNext();) {
            diameter.offerLast(it.next());
        }

        diameter.offerLast(this.root.item);

        for (Iterator<T> it = diameterRightPart.descendingIterator(); it.hasNext();) {
            diameter.offerLast(it.next());
        }

        return diameter;
    }

    private void diameter(Node node, Deque<T> diameter) {
        if (node == null)  {
            return;
        }

        Deque<T> leftPart = new ArrayDeque<T>();
        Deque<T> rightPart = new ArrayDeque<T>();

        diameter(node.left, leftPart);
        diameter(node.right, rightPart);

        if (leftPart.size() > rightPart.size()) {
            diameter.addAll(leftPart);
        } else {
            diameter.addAll(rightPart);
        }

        diameter.offerLast(node.item);
    }

    ...
}
public class TreeDiameter {
    public static void main(String[] args) {
        Tree<Integer> tree = new BinarySearchTree<Integer>();
        tree.add(5);
        tree.add(2);
        tree.add(8);
        tree.add(1);
        tree.add(3);
        tree.add(7);
        tree.add(9);
        tree.add(4);
        tree.add(6);

        for (Integer diameterNode : tree.diameter()) {
            System.out.print(diameterNode + " ");
        }
    }
}
4 3 2 5 8 7 6