i am trying to print all root to leaf paths in a binary tree using java.
public void printAllRootToLeafPaths(Node node,ArrayList path)
{
if(node==null)
You can do the following,
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;
}
Here is my solution: Once we traverse the left or right path just remove the last element.
Code:
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("");
}
Call the recursive methods with:
printAllRootToLeafPaths(node.left, new ArrayList(path));
printAllRootToLeafPaths(node.right, new ArrayList(path));
What happens there when you pass the path
(instead of new ArrayList(path)
is that you use a single object in all methods call, which means that, when you return to the original caller, the object is not in the same state as it was.
You just need to create a new object and initialize it to the original values. This way the original object does not get modified.
I tried this problem with an ArrayList
and my program printed similar paths.
So I modified my logic to work correctly by maintaining an internal count
, here is how I did it.
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);
}
We can use recursion to achieve it. Right data structure makes it concise and efficient.
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;
}