tree traversal result in a list - java

I have looked into tree traversal methods, but most of them use void modifiers and just printed the traversal sequence. Instead, is there a way to make a list of the sequence using recursion in Java?
The starter code is below.
Since preorder is List<T>, it should return a list, but global variables are not allowed. Then, there should be a list instance within the preorder method, but because it is recursive, the list will be created repetitively as well. I am stuck. Could someone versed in algorithm and Java help me with this?
public class Traversals<T extends Comparable<? super T>> {
//no global variables allowed
public List<T> preorder(TreeNode<T> root) {
// CODE HERE.
}
}
public class TreeNode<T extends Comparable<? super T>> {
private T data;
private TreeNode<T> left;
private TreeNode<T> right;
TreeNode(T data) {
this.data = data;
}
T getData() {
return data;
}
TreeNode<T> getLeft() {
return left;
}
TreeNode<T> getRight() {
return right;
}
void setData(T data) {
this.data = data;
}
void setLeft(TreeNode<T> left) {
this.left = left;
}
void setRight(TreeNode<T> right) {
this.right = right;
}
}
i could do It iteratively, but I do not know how to do recursively.

Using just the preorder(TreeNode<T>) method
This should also work and satifies all your contraints. A new list empty list is created every time and enriched with the list from the left and the right branch of the recursion.
public class Traversals<T extends Comparable<? super T>> {
//no global variables allowed
public List<TreeNode<T>> preorder(TreeNode<T> root) {
var preorderLst = new LinkedList<TreeNode<T>>();
if(root != null) {
preorderLst.add(root);
var leftList = preorder(root.getLeft());
var rightList = preorder(root.getRight());
preorderLst.addAll(leftList);
preorderLst.addAll(rightList);
}
return preorderLst;
}
}
Using a 2nd private method
Admittedly not the nicest solution but a simple working solution.
public class Traversals<T extends Comparable<? super T>> {
//no global variables allowed
public List<TreeNode<T>> preorder(TreeNode<T> root) {
var preorderLst = new LinkedList<TreeNode<T>>();
preorder(root, preorderLst);
return preorderLst;
}
private void preorder(TreeNode<T> root, List<TreeNode<T>> preorderLst){
if(root == null) return;
preorderLst.add(root);
preorder(root.getLeft(), preorderLst);
preorder(root.getRight(), preorderLst);
}
}
If you just need the data for a List<T> you would just need to call .getData() when adding root to the list.

Related

Using an outer field only for one method

I am implementing a recursive in-order traversal for a binary tree and want to save the data for each node in a list inOrderList which is modified only by this method. defining the list in the inOrder function is a problem because it is recursive. not sure where to declare the list, maybe I should change the structure of the project, how should I implement this functionality with best practices?
class TreeNode {
private TreeNode left;
private TreeNode right;
private Integer data;
public TreeNode(TreeNode left, TreeNode right, Integer data) {
this.left = left;
this.right = right;
this.data = data;
}
// getters..
}
class TreeOperations {
public static void inOrder(TreeNode node) {
if (node == null) return;
inOrder(node.getLeft());
inOrderList.add(node.getData()); // where to define ArrayList<Integer> inOrderList?
inOrder(node.getRight());
}
// many more methods not using inOrderList
}
Have a helper function which does the actual recursion, i.e.:
public static List<Integer> inOrder(TreeNode node) {
final List<Integer> inOrderList = new ArrayList<Integer>();
inOrderHelper(node, inOrderList);
return inOrderList;
}
private static void inOrderHelper(TreeNode node, List<Integer> inOrderList) {
if (node == null) return;
inOrderHelper(node.getLeft(), inOrderList);
inOrderList.add(node.getData());
inOrderHelper(node.getRight(), inOrderList);
}

Implementing certain methods in a BST class

Consider the following definitions of BSTNode and BST classes:
public class BSTNode<T extends Comparable<? super T>> {
protected T el;
protected BSTNode<T> left, right;
public BSTNode() {
left = right = null;
}
public BSTNode(T el) {
this(el,null,null);
}
public BSTNode(T el, BSTNode<T> lt, BSTNode<T> rt) {
this.el = el; left = lt; right = rt;
}
}
public class BST<T extends Comparable<? super T>> {
protected BSTNode<T> root = null;
public BST() {
}
….
}
how can i implement a method in class BST to count the number of right children in a BST
To my understanding, the number of right children of a node can be counted recursively as follows.
First, implement a recursive method in the BSTNode class.
public int GetNumOfRightChildren()
{
int Result = 0;
if (null != right)
Result = 1 + right.GetNumOfRightChildren();
return Result;
}
Next, this method could be made accessible in a very similar way in the BST class as follows.
public int GetNumOfRightChildren()
{
int Result = 0;
if (null != root)
Result = 1 + root.GetNumOfRightChildren();
return Result;
}
If changing the implementation of BSTNode is not permitted, the task cannot be solved as the right and left subtrees in BSTNode are inaccessible from the BST class.

Binary Tree Generic Problemm

Currently studying for an exam, and I stuck at Generic Binary Tree
public interface BinaryTreeNode <T>{
public void setParent(T binaryTreeNodeImpl);
public void setLeft(T left);
public void setRight(T right);
public T getRoot() ;
public T getParent();
public void setValue(T string);
public T getLeft();
}
İt is my interface.
public class BinaryTreeNodeImpl <T> implements BinaryTreeNode <T>{
public T value;
private T Root;
private T right;
private T parent;
private T left;
public void setRight(T right) {
this.right = right;
( (BinaryTreeNode<T>) right).setParent( (T) this);
}
public T getRoot() {
return (T) Root;
}
public void setValue(T value) {
this.value=value;
}
public T getValue() {
return value;
}
public T getParent() {
return parent;
}
public void setParent(T binaryTreeNodeImpl) {
parent= binaryTreeNodeImpl;
}
public T getRight() {
return right;
}
public T getLeft() {
return left;
}
public void setLeft(T left) {
this.left = left;
( (BinaryTreeNode<T>) left).setParent((T) this);
}
}
it is my Binary Tree Implement .When I try to run. Bellow code I've got Value method is undefined for String.
BinaryTreeNode<String> root = new BinaryTreeNodeImpl<String>();
root.setValue("abc");
BinaryTreeNode<String> left = new BinaryTreeNodeImpl<String>();
left.setValue("xyz");
root.setLeft(left);
System.out.println(left.getParent().getValue());
System.out.println(root.getLeft().getValue());
I did not understand where I did wrong ? Should I create abstract method for that ?
The reason that you had the error is that getParent() and getLeft() return T, which is String, when you meant to return a node here.
Your references to root, parent, left, and right in your BinaryTreeNode interface have type T, but that is the type of data that the node needs to reference, not the node itself. Change the datatype of the return values and parameters of the methods that don't have anything to do with the value from T to BinaryTreeNode<T>. This will of course affect the same declarations in your implementing class BinaryTreeNodeImpl.
Your getParent() has a return type T; I am under the impression that you want this to be BinaryTreeNode<T> since a parent of a BinaryTreeNode should be a binary tree node (preferably of the same type).
Your current design is akin to saying that the parent of a BinaryTreeNode can be a String or an Integer or a cat and you are calling the getValue() on that, which obviously is not defined, hence the error.
Make the same edits to the return types in the method declarations in your interface.

Level traversal in binary tree

Here is the part of code of the binary tree class that I'm writing.
class Node<T> {
private T value;
private Node<T> left;
private Node<T> right;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
public Node() {}
public Node(T value) {
this.value = value;
}
public Node(T value, Node<T> left, Node<T> right) {
this.value = value;
this.left = left;
this.right = right;
}
}
import java.util.*;
public class Tree<T extends Comparable<T>> {
private Node<T> root;
private List<T> levelOrderList = new ArrayList<T>();
public Node<T> getRoot() {
return root;
}
public Tree() {
}
public Tree(Node<T> root) {
this.root = root;
}
private List<T> getLevelOrderList(Node<T> root){
if (root == null)
return Collections.emptyList();
Queue<Node<T>> level = new LinkedList<Node<T>>();
level.add(root);
while(!level.isEmpty()){
Node<T> node = level.poll();
levelOrderList.add(node.getValue());
if(node.getLeft() != null)
level.add(node.getLeft());
if(node.getRight() != null)
level.add(node.getRight());
}
return levelOrderList;
}
public List<T> getLevelOrderList() {
return getLevelOrderList(root);
}
}
The method getLevelOrderList() returns list of elements in tree in level by level order.
The question is: how to rewrite method getLevelOrderList using recursion?
What you need to do is remove the loop, and just focus on a single pass through what now is in the loop. You'll need to move some of that code out of the private method and into the public method you created. Like the check for root == null, level instantiation, etc. Then you'll just keep calling the private method until level is empty. Here is how I'd change the signature:
public List<T> getLevelOrderList() {
if( root == null ) return Collections.emptyCollection();
List<Node<T>> level = new ArrayList<Node<T>>();
List<T> values = new ArrayList<T>();
level.add( root );
return getLevelOrderList( level, values );
}
private List<T> getLevelOrderList(List<Node<T>> level, List<T> values) {
if( level.isEmpty() ) return values;
// do the next step to visit the node at the head of the list and recurse
}
That should be enough to get you started, but I can't give this away since it's clearly homework. Oh and your program had a bug if you called getLevelOrderList() twice it would never clear out the instance variable you had so it would return double the number of items from the tree. By not using instance variables I removed that bug.

How do I use Java's Comparable to compare Generic objects in a tree?

Right now I'm trying to do an assignment involving creating a heap that can receive any generic object, and the nodes can compare each other by implementing the Comparable interface. Problem is, I can't find a way to compare generic object like this.
This is what I have so far for the Node class:
private class Node<E> implements Comparable<E>
{
private E data;
private Node left;
private Node right;
//constructors
public Node(E data)
{
this.data = data;
left = null;
right = null;
}
public Node(E data, Node left, Node right)
{
this.data = data;
this.left = left;
this.right = right;
}
//returns current data
public Object getData()
{
return this.data;
}
public int compareTo(E other)
{
return data.compareTo(other);
}
}
When I try to compile, it says "Cannot find symbol -- Method compareTo(E)." The method compareTo() is in the Comparable interface, so I can't understand why this is happening, and I don't know how to fix it. Anyone have any idea?
You need to define E as Comparable as well:
private class Node<E extends Comparable<E>> implements Comparable<E>
Also, it would probably make more sense to have your Node class comparable to itself:
private class Node<E extends Comparable<E>> implements Comparable<Node<E>>
...
public int compareTo(Node<E> other)
{
return data.compareTo(other.data);
}
Okay, so a couple of things with your code:
// E needs to be restricted to the Comparable interface
// Also, You probably mean for Nodes to be comparable with each other
public class Node<E extends Comparable<E>> implements Comparable<Node<E>>
{
private E data;
// Remember to specify your generic parameter in references to Node as well!
private Node<E> left;
private Node<E> right;
//constructors
public Node(E data)
{
this.data = data;
left = null;
right = null;
}
public Node(E data, Node<E> left, Node<E> right)
{
this.data = data;
this.left = left;
this.right = right;
}
//returns current data
// This should return your E generic type, not Object.
public E getData()
{
return this.data;
}
// This now compares to a Node.
public int compareTo(Node<E> other)
{
return data.compareTo(other.getData());
}
}

Categories

Resources