[英]print all root to leaf paths in a binary tree
我正在尝试使用 java 在二叉树中打印所有根到叶路径。
public void printAllRootToLeafPaths(Node node,ArrayList path)
{
if(node==null)
{
return;
}
path.add(node.data);
if(node.left==null && node.right==null)
{
System.out.println(path);
return;
}
else
{
printAllRootToLeafPaths(node.left,path);
printAllRootToLeafPaths(node.right,path);
}
}
在主要方法中:
bst.printAllRootToLeafPaths(root, new ArrayList());
但它给出了错误的输出。
给定的树:
5
/ \
/ \
1 8
\ /\
\ / \
3 6 9
预期输出:
[5, 1, 3]
[5, 8, 6]
[5, 8, 9]
但产生的输出:
[5, 1, 3]
[5, 1, 3, 8, 6]
[5, 1, 3, 8, 6, 9]
有大佬能解一下吗...
调用递归方法:
printAllRootToLeafPaths(node.left, new ArrayList(path));
printAllRootToLeafPaths(node.right, new ArrayList(path));
当你传递path
时会发生什么(而不是new ArrayList(path)
是你在所有方法调用中使用单个对象,这意味着,当你返回原始调用者时,对象与其处于不同的状态曾是。
您只需要创建一个新对象并将其初始化为原始值。 这样原始对象不会被修改。
public void PrintAllPossiblePath(Node node,List<Node> nodelist)
{
if(node != null)
{
nodelist.add(node);
if(node.left != null)
{
PrintAllPossiblePath(node.left,nodelist);
}
if(node.right != null)
{
PrintAllPossiblePath(node.right,nodelist);
}
else if(node.left == null && node.right == null)
{
for(int i=0;i<nodelist.size();i++)
{
System.out.print(nodelist.get(i)._Value);
}
System.out.println();
}
nodelist.remove(node);
}
}
nodelist.remove(node)
是键,它在打印相应的路径后删除元素
您正在递归地传递您的列表,但这是一个可变对象,因此所有调用都将修改它(通过调用List.add
)并破坏您的结果。 尝试将path
参数克隆/复制到所有递归调用,以提供每个分支 (harhar) 自己的上下文。
你也可以这样做。 这是我的 Java 代码。
public void printPaths(Node r,ArrayList arr)
{
if(r==null)
{
return;
}
arr.add(r.data);
if(r.left==null && r.right==null)
{
printlnArray(arr);
}
else
{
printPaths(r.left,arr);
printPaths(r.right,arr);
}
arr.remove(arr.size()-1);
}
这是正确的实现
public static <T extends Comparable<? super T>> List<List<T>> printAllPaths(BinaryTreeNode<T> node) {
List <List<T>> paths = new ArrayList<List<T>>();
doPrintAllPaths(node, paths, new ArrayList<T>());
return paths;
}
private static <T extends Comparable<? super T>> void doPrintAllPaths(BinaryTreeNode<T> node, List<List<T>> allPaths, List<T> path) {
if (node == null) {
return ;
}
path.add(node.getData());
if (node.isLeafNode()) {
allPaths.add(new ArrayList<T>(path));
} else {
doPrintAllPaths(node.getLeft(), allPaths, path);
doPrintAllPaths(node.getRight(), allPaths, path);
}
path.remove(node.getData());
}
这是测试用例
@Test
public void printAllPaths() {
BinaryTreeNode<Integer> bt = BinaryTreeUtil.<Integer>fromInAndPostOrder(new Integer[]{4,2,5,6,1,7,3}, new Integer[]{4,6,5,2,7,3,1});
List <List<Integer>> paths = BinaryTreeUtil.printAllPaths(bt);
assertThat(paths.get(0).toArray(new Integer[0]), equalTo(new Integer[]{1, 2, 4}));
assertThat(paths.get(1).toArray(new Integer[0]), equalTo(new Integer[]{1, 2, 5, 6}));
assertThat(paths.get(2).toArray(new Integer[0]), equalTo(new Integer[]{1, 3, 7}));
for (List<Integer> list : paths) {
for (Integer integer : list) {
System.out.print(String.format(" %d", integer));
}
System.out.println();
}
}
1 2 4 1 2 5 6 1 3 7
这是我的解决方案:一旦我们遍历左侧或右侧路径,只需删除最后一个元素。
代码:
public static void printPath(TreeNode root, ArrayList list) {
if(root==null)
return;
list.add(root.data);
if(root.left==null && root.right==null) {
System.out.println(list);
return;
}
else {
printPath(root.left,list);
list.remove(list.size()-1);
printPath(root.right,list);
list.remove(list.size()-1);
}
}
/* Given a binary tree, print out all of its root-to-leaf
paths, one per line. Uses a recursive helper to do the work.*/
void printPaths(Node node)
{
int path[] = new int[1000];
printPathsRecur(node, path, 0);
}
/* Recursive helper function -- given a node, and an array containing
the path from the root node up to but not including this node,
print out all the root-leaf paths. */
void printPathsRecur(Node node, int path[], int pathLen)
{
if (node == null)
return;
/* append this node to the path array */
path[pathLen] = node.data;
pathLen++;
/* it's a leaf, so print the path that led to here */
if (node.left == null && node.right == null)
printArray(path, pathLen);
else
{
/* otherwise try both subtrees */
printPathsRecur(node.left, path, pathLen);
printPathsRecur(node.right, path, pathLen);
}
}
/* Utility that prints out an array on a line */
void printArray(int ints[], int len)
{
int i;
for (i = 0; i < len; i++)
System.out.print(ints[i] + " ");
System.out.println("");
}
我用ArrayList
尝试了这个问题,我的程序打印了类似的路径。
因此,我通过维护内部count
来修改我的逻辑以使其正常工作,这就是我的做法。
private void printPaths(BinaryNode node, List<Integer> paths, int endIndex) {
if (node == null)
return;
paths.add(endIndex, node.data);
endIndex++;
if (node.left == null && node.right == null) {
//found the leaf node, print this path
printPathList(paths, endIndex);
} else {
printPaths(node.left, paths, endIndex);
printPaths(node.right, paths, endIndex);
}
}
public void printPaths() {
List<Integer> paths = new ArrayList<>();
printPaths(root, paths, 0);
}
我们可以使用递归来实现。 正确的数据结构使其简洁高效。
List<LinkedList<Tree>> printPath(Tree root){
if(root==null)return null;
List<LinkedList<Tree>> leftPath= printPath(root.left);
List<LinkedList<Tree>> rightPath= printPath(root.right);
for(LinkedList<Tree> t: leftPath){
t.addFirst(root);
}
for(LinkedList<Tree> t: rightPath){
t.addFirst(root);
}
leftPath.addAll(rightPath);
return leftPath;
}
您可以执行以下操作,
public static void printTreePaths(Node<Integer> node) {
int treeHeight = treeHeight(node);
int[] path = new int[treeHeight];
printTreePathsRec(node, path, 0);
}
private static void printTreePathsRec(Node<Integer> node, int[] path, int pathSize) {
if (node == null) {
return;
}
path[pathSize++] = node.data;
if (node.left == null & node.right == null) {
for (int j = 0; j < pathSize; j++ ) {
System.out.print(path[j] + " ");
}
System.out.println();
}
printTreePathsRec(node.left, path, pathSize);
printTreePathsRec(node.right, path, pathSize);
}
public static int treeHeight(Node<Integer> root) {
if (root == null) {
return 0;
}
if (root.left != null) {
treeHeight(root.left);
}
if (root.right != null) {
treeHeight(root.right);
}
return Math.max(treeHeight(root.left), treeHeight(root.right)) + 1;
}
这是我将所有路径值存储在 List 中然后只打印列表的解决方案
基本上什么代码递归调用 rootToLeafPaths 方法并在以逗号(“,”)分隔的值上传递字符串。 递归函数的基本条件是当我们到达叶节点时(两个子节点都为空)。 那时,我们只是从字符串中提取 int 值并将其存储在 List 中
class Solution {
public void printBTfromRootToLeaf (TreeNode root) {
if(root == null) return 0;
if (root.left == null & root.right == null) return 1;
List<List<Integer>> res = new ArrayList();
rootToLeafPaths(root, res, "");
System.out.println(res);
}
private void rootToLeafPaths(TreeNode root, List<List<Integer>> res, String curr) {
if (root.left == null && root.right == null) {
String[] vals = curr.split(",");
List<Integer> temp = new ArrayList<>();
for (String val : vals) temp.add(Integer.parseInt(val));
temp.add(root.val);
res.add(new ArrayList<>(temp));
}
if (root.left != null) rootToLeafPaths(root.left, res, curr + root.val + ",");
if (root.right != null) rootToLeafPaths(root.right, res, curr + root.val + ",");
}
}
它是用 JS 编写的,但您可以获得逻辑。
function dive(t, res, arr) {
if(t.value != null && t.value != undefined) {
res = res ? `${res}->${t.value}`: `${t.value}`;
}
if(t.left) {
dive(t.left, res, arr );
}
if(t.right) {
dive(t.right, res, arr );
}
if(!t.left && !t.right) {
console.log(res)
arr.push(res);
return;
}
}
function getPaths(t) {
let arr = [];
if(!t.left && !t.right) {
t.value != null && t.value != undefined && arr.push(`${t.value}`);
console.log(arr)
return arr;
}
dive(t, null, arr);
console.log(arr)
}
//INPUT
const x = {
value: 5,
left: {
value: 4,
left: {
value: 3,
left: {
value: 2,
left: {
value: 1,
left: {
value: 0
},
right: {
value: 1.5
}
},
right: {
value: 2.5
}
},
right: {
value: 3.5
}
},
right: {
value: 4.5,
right: {
value: 4.8
}
}
},
right: {
value: 8,
left: {
value: 7
}
}
}
getPaths(x);
//OUTPUT
[ '5->4->3->2->1->0',
'5->4->3->2->1->1.5',
'5->4->3->2->2.5',
'5->4->3->3.5',
'5->4->4.5->4.8',
'5->8->7' ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.