Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中,无需使用递归即可在二叉树中打印给定输入节点的祖先节点_Java_Algorithm_Binary Tree - Fatal编程技术网

在java中,无需使用递归即可在二叉树中打印给定输入节点的祖先节点

在java中,无需使用递归即可在二叉树中打印给定输入节点的祖先节点,java,algorithm,binary-tree,Java,Algorithm,Binary Tree,如何在不使用递归的情况下获取二叉树的祖先节点。我有下面使用递归的代码,但无法理解如何在不使用递归的情况下获取 boolean printAncestors(Node node, int target) { /* base cases */ if (node == null) { return false; } if (node.data == target) { return true; } /*

如何在不使用递归的情况下获取二叉树的祖先节点。我有下面使用递归的代码,但无法理解如何在不使用递归的情况下获取

boolean printAncestors(Node node, int target) {        
    /* base cases */
    if (node == null) {
        return false;
    }

    if (node.data == target) {
        return true;
    }

    /* If target is present in either left or right subtree of this node then print this node */
    if (printAncestors(node.left, target) || printAncestors(node.right, target)) {
        System.out.print(node.data + " ");
        return true;
    }

    /* Else return false */
    return false;
}

一种简单的方法包括某种类型的“待办事项列表”,以及跟踪祖先的
Map
。待办事项列表可以是队列或堆栈。基本计划如下:

  • 初始化待办事项列表以仅包含根目录
  • 当待办事项列表不为空时:
    • 从待办事项列表中获取下一个节点N
    • 如果N是你的目标,停止
    • 如果N.left不为null,则将(N.left,N)添加到“祖先”映射中。此映射将允许您找到所访问的任何节点的祖先
    • 如果N.right不为null,则将(N.right,N)添加到“祖先”映射中
    • 如果N.left不为空,则将其添加到待办事项列表中
    • 如果N.right不为null,则将其添加到待办事项列表中
在这一点上,目标的父母、祖父母等,一路向上,都会出现在“祖先”地图上,所以打印所有祖先应该很容易

如果将堆栈用于待办事项列表,则应在
N.left
之前将
N.right
推到堆栈上。然后您将按预定顺序遍历树

如果对待办事项列表使用队列,以便将元素添加到末尾并从开头检索它们,那么我认为遍历顺序将是广度优先搜索,在该搜索中,我们遍历根,然后遍历下一级别上的所有节点,然后遍历下一级别上的所有节点,等等


这是我能想到的最简单的答案,它可以提供一个模板,说明如何在不使用递归的情况下解决其他树遍历问题。(另外,如果您添加逻辑以确保不会访问节点两次,它也适用于其他类型的图形。)就空间效率而言,这不是最佳答案。经过一些思考,您可以想出一种算法,它不使用
映射,也不将节点的两个子节点都推到堆栈或队列上(这样最大堆栈大小将更小)。

一种简单的方法包括某种“待办事项列表”,以及一个
映射来跟踪祖先。待办事项列表可以是队列或堆栈。基本计划如下:

  • 初始化待办事项列表以仅包含根目录
  • 当待办事项列表不为空时:
    • 从待办事项列表中获取下一个节点N
    • 如果N是你的目标,停止
    • 如果N.left不为null,则将(N.left,N)添加到“祖先”映射中。此映射将允许您找到所访问的任何节点的祖先
    • 如果N.right不为null,则将(N.right,N)添加到“祖先”映射中
    • 如果N.left不为空,则将其添加到待办事项列表中
    • 如果N.right不为null,则将其添加到待办事项列表中
在这一点上,目标的父母、祖父母等,一路向上,都会出现在“祖先”地图上,所以打印所有祖先应该很容易

如果将堆栈用于待办事项列表,则应在
N.left
之前将
N.right
推到堆栈上。然后您将按预定顺序遍历树

如果对待办事项列表使用队列,以便将元素添加到末尾并从开头检索它们,那么我认为遍历顺序将是广度优先搜索,在该搜索中,我们遍历根,然后遍历下一级别上的所有节点,然后遍历下一级别上的所有节点,等等


这是我能想到的最简单的答案,它可以提供一个模板,说明如何在不使用递归的情况下解决其他树遍历问题。(另外,如果您添加逻辑以确保不会访问节点两次,它也适用于其他类型的图形。)就空间效率而言,这不是最佳答案。经过一些思考,您可以提出一种算法,该算法不使用
映射
,并且不会将节点的两个子节点都推送到堆栈或队列上(这样最大堆栈大小将更小)。

感谢您的回复。感谢您的回复。