Implementing certain methods in a BST class - java

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.

Related

tree traversal result in a list

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.

Java extending parameterized class

I'm having trouble trying to figure out the following. Imagine that I have the generic class Node<T> for representing the nodes of a binary tree, with some methods in it.
public class Node<T> {
T info;
Node<T> left;
Node<T> right;
public Node(T info) {this.info=info;}
//and some methods
}
Now I would like to add a method for Nodes of type Integer, which would sum all the nodes that can be reached from the current one:
public int sum(){
int sum = this.info;
if(this.left!=null) sum+=left.sum();
if(this.right!=null) sum+=right.sum();
return sum;
}
I am not quite sure how to do this. I thought of creating a class that extends Node<Integer> and adding the method sum there:
public class NodeOfIntegers extends Node<Integer>{
public NodeOfIntegers (T info) {super();}
public int sum(){...}
}
but since left and right are of type Node<Integer> and not NodeOfIntegers I can't do left.sum() and right.sum().
Is there a way to do this without redefining left and right?
Thank you very much.
Use a reduce function like the Stream provides:
public static class Node<T>{
public Node(T value, Node<T> a, Node<T> b){
this.value = value;
this.a = a;
this.b = b;
}
private final Node<T> a,b;
private final T value;
private T reduce(T start,BinaryOperator<T> operator){
T reduced = operator.apply(start,value);
if(a != null)reduced = a.reduce(reduced,operator);
if(b != null)reduced = b.reduce(reduced,operator);
return reduced;
}
}
public static void main(String[] args) {
Node<Integer> integerNode = new Node<>(4,new Node<>(4,null,null),new Node<>(2,null,null));
System.out.println(integerNode.reduce(0, Integer::sum));
}
You should define your T as
class Node<T extends Number> {
}
then you can write the function of sum as
int sum() {
int sum = this.info.intValue();
}
Instead of using a NodeOfInteger class, I would define in the Node class a
public T combine(BinaryOperator<T> combiner) {
T res = this.info;
if (this.left != null) res = combine(res, this.left.combine(combiner);
if (this.right != null) res = combine(res, this.right.combine(combiner);
return res;
}
which can be used as node.combine(Integer::sum), or as node.combine(String::concat)
(Note that this can be defined outside of the Node class if needed)

Java: Implementing parallel hierarchy of trees and its nodes

In order to practice data structures I'm implementing my own library of Trees. I've begun with BST and in following I'm about to implement AVL Tree, Red-Black Tree and maybe more. AVL & RBT are BST trees as well, so some class hierarchy is rather obvious. The problem I came into is that all those trees have other types of Nodes - AvlNode has balance factor flag, RgbNode has color flag, BstNode doesn't need any additional info (despite of references to parent, children and value which all Nodes need). So I've a hierarchy of Nodes and a hierarchy of Trees. I could give some flag attribute to BstNode and use it in extending classes but it is surely not a good way to do it.
The problem is how to deal with the fact that for example Bst.findNode() will return BstNode but in Avl I need AvlNode despite the findNode() methods will be the same in both (apart of return type).
I need help with planning the hierarchies or if those parallel hierarchies (as a code smell) are in general a bad idea, I need a workaround because I have no clue how to do it in proper way.
BstTree Class:
public class BstTree<T extends Comparable> implements Iterable
{
private BstNode<T> root;
public void addValue(T value)
{
BstNode node = new BstNode(value);
addNode(node);
}
public void addNode(BstNode<T> node)
{
...
}
public boolean removeNode(T value)
{
...
}
public BstNode findNode(T value)
{
...
}
//other less significant methods
}
BstNode class:
public class BstNode<T extends Comparable>
{
private static int lastId = 0;
private int id;
private T value;
private BstNode parent = null;
private BstNode leftChild = null;
private BstNode rightChild = null;
public BstNode(T value) {
this.id = ++lastId;
this.value = value;
}
public boolean isGreaterThan(BstNode n)
{
//...
}
public boolean hasLeftChild()
{
//...
}
public boolean hasRightChild()
{
//...
}
public boolean hasParent()
{
//...
}
public boolean isLeaf()
{
//...
}
public boolean hasOnlyOneChild()
{
//...
}
public BstNode getOnlyChild(BstNode node)
{
...
}
public boolean isLeftChildren()
{
...
}
public BstNode getConsequentNode()
{
...
}
}
I can guess that the separation of responsibilities above may not be perfect, if it's wrong then I might get some of the methods from Node to Tree class but this thing is not a big problem.
I would do something like this:
public abstract class BstTree<T extends Comparable,N extends BstNode<T,N>> {
private N root;
...
public void addValue(T value)
{
N node = newNode(value);
addNode(node);
}
public abstract N newNode(T value);
public void addNode(N node)
{
// ...
}
}
public class BstNode<T extends Comparable,N extends BstNode<T,N>>
{
private T value;
private N parent = null;
private N leftChild = null;
private N rightChild = null;
public BstNode(T value) {
this.value = value;
}
public N getOnlyChild(N node)
{
// ...
}
...
}
public class AVLTree<T extends Comparable> extends BstTree<T,AVLNode<T>> {
...
#Override
public AVLNode<T> newNode(T value) {
return new AVLNode<>(value);
}
}
public class AVLNode<T extends Comparable> extends BstNode<T,AVLNode<T>> {
...
public AVLNode(T value) {
super(value);
}
#Override
public AVLNode<T> getOnlyChild(AVLNode<T> node) {
return super.getOnlyChild(node);
}
...
}

Java Generics in a Binary Tree, incompatible types error

I'm trying to implement a Binary Tree in java with Generics, i searched and i find this question: Implementing Binary Tree in Java with Generic Comparable<T> data?, but i couldn't resolve my doubts. So i have two classes,
BST_Tree<T>
and
Node<T extends Comparable<T>>
I want that my implementation can:
Take every type of Object and put it inside the field key in Node
Compare every node with the key field
This is the code:
public class Node < T extends Comparable < T >> {
private T key;
private Node left;
private Node right;
private Node p;
public void setKey(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
public void setP(Node p) {
this.p = p;
}
public boolean getBolCompMin(T key) {
return this.key.compareTo(key) < 0;
}
}
My Node class is suppose to extend Comparable in order to compare the key.
This is my tree:
public class BST_Tree < T > {
private ArrayList < Node > nodes;
private Node root;
public BST_Tree(Node root) {
this.root = root;
}
public void insertNode(T key) {
Node z = new Node();
z.setKey(key);
Node x = this.root;
Node y = new Node();
while (x != null) {
y = x;
if (z.getBolCompMin(x.getKey())) {
x = x.getLeft();
} else {
x = x.getRight();
}
}
z.setP(y);
if (z.getBolCompMin(y.getKey())) {
y.setLeft(z);
} else {
y.setRight(z);
}
}
public void InOderWalk(Node x) {
if (x != null) {
InOderWalk(x.getLeft());
System.out.println(x.getKey());
InOderWalk(x.getRight());
}
}
public Node getRoot() {
return root;
}
}
My tree tries to set the key in node z but it fails. This is the error:
incompatible types: T cannot be converted to java.lang.Comparable
Thank you in advance!
Your
public class BST_Tree<T>
should be
public class BST_Tree<T extends Comparable<T>>
And every Node variable inside your BST_Tree and Node classes should be Node<T>.
This would ensure that you can only instantiate your BST_Tree class with element types that implement Comparable.

Binary Search Tree Cloning - Java

It's a homework problem. we need to build a method in java that clones a given binary search tree through recursion, ive looked up several examples online, the problem being that the program our instructor asked us to write was in what he called the Modern method, whereby rather than checking for null in each method, a tree is constructed using Dynamic dispatch from an Interface Node, connected to two subclasses nil(representing an empty node and the necessary methods to deal with an instance of an empty Node) and Vertex, a filled node and its affiliate methods. im confused on how to structure the recursion to clone the nodes, and construct the nodes to hold the cloned info. this being homework im obviously not looking for an answer but i really need some help with this.
interface Node<T extends Comparable<T>>
{
public int size();//return the number of values in the tree
public boolean empty();//true if tree is empty nil
public Node<T> insert(T x);// insert something into a binary search tree, return the node it was inserted into
public vertex<T> search(T x);//search for a given value and return the vertex ( filled node ) it exists in
public int depth();//returns the greatest depth of the tree
public void inorder();
//public Node<T> Attack_of_the_clones();
}
//note that insert must be used as in t = t.insert(x)
class nil<T extends Comparable<T>> implements Node<T> //empty tree
{
public int size() {return 0;}// empty node, therefore of size zero
public boolean empty() { return true; }//its and empty node, duh
public Node<T> insert(T x) { return new vertex<T>(x); }// returns a Tpe Node for inserting a given value into a node (thereby creating a
//vertex containing said inserted value)
public vertex<T> search (T x) { return null; }//RETURNS NULL IN SEARCHING FOR A GIVE VALUE BECAUSE NODES OF TPE nIL ARE INHERENTLY empty
public int depth() { return 0; }
public void inorder() { System.out.print("0");}
//public Node<T> Attack_of_the_clones() { return new nil<T>(this); }
}//end nil
class vertex<T extends Comparable<T>> implements Node<T>
{
protected T head;// the root of the tree
protected Node<T> left;//creates an instance of Node to serve as the left child of head
protected Node<T> right;
//constructor
public vertex(T h, Node<T> l, Node<T> r) { head = h; left = l; right = r; }// a constructed instance
//leaf instructor
public vertex(T h) { head = h; left = new nil<T>(); right = new nil<T>(); }//a constructed leaf
// a leaf is Tpically a node with no or null children, some consider the null nodes themselves to be leaves
//accesors so that the protected variables can be displayed
public T acHead() {return head;}
public Node<T> acLeft() {return left;}
public Node<T> acRight() {return right;}
public int size()
{
return left.size() + right.size() + 1;//recursively call size down the left and right trees to get all the nodes,
// and combine them ( +1 for the root) to get the size of the tree
}
public int depth()
{
return Math.max((left.depth()+1),(right.depth()+1));
}
public boolean empty() {return false; }//because its of class vertex and therefore not empty
public Node<T> insert(T x)
{
if (x.compareTo(head) <= 0)// go down left tree
left = left.insert(x);
else right = right.insert(x);// go right
return this;//root vertex has not changed
}//end insert
public vertex<T> search(T x)
{
int r = x.compareTo(head);
if(r==0)//go left
{
return left.search(x);//recursively call search using said node to move down tree
}
else //go right
{
return right.search(x);
}
}// end binary search
public void inorder()
{
Node<T> current_root = this;
if(current_root == null)
return;
left.inorder();
System.out.println(current_root + ", ");
right.inorder();
}//end inorder print
/*public Node<T> Attack_of_the_clones()
{
left_copy = curr_node.left.copy();
right_copy = curr_node.right.copy();
return new vertex(curr_node, left1, right1);
}*/
public vertex<T> largest(Node<T> x)
{
int left1 = largest(x.left);
int right1 = right.largest();
if(this.head > left1 && this.head > right1)
return this.root;
else
return Math.max(left1,right1);
}
}// end vertex
public class BinaryTree
{
public static void main(String[] args)
{
Node<Integer> n = new vertex<Integer>(3);
n = n.insert(4);
for(int i = 0; i < 10; i++)
{
n.insert((int)Math.random*8);
}
n.size();
n.depth();
n.inorder();
}//end main
}//end Binary Tree
BinaryTree.java:87: warning: [rawtypes] found raw type: vertex
public Node<T> Attack_of_the_clones() { return new vertex(head, left.Attack_of_the_clones(), right.Attack_of_the_clones());}
^
missing type arguments for generic class vertex<T>
where T is a type-variable:
T extends Comparable<T> declared in class vertex
BinaryTree.java:87: warning: [unchecked] unchecked call to vertex(T,Node<T>,Node<T>) as a member of the raw type vertex
public Node<T> Attack_of_the_clones() { return new vertex(head, left.Attack_of_the_clones(), right.Attack_of_the_clones());}
^
where T is a type-variable:
T extends Comparable<T> declared in class vertex
BinaryTree.java:87: warning: [unchecked] unchecked conversion
public Node<T> Attack_of_the_clones() { return new vertex(head, left.Attack_of_the_clones(), right.Attack_of_the_clones());}
^
required: Node<T>
found: vertex
where T is a type-variable:
T extends Comparable<T> declared in class vertex
3 warnings
As Nil has no fields (is immutable) then its clone can just return itself.
//On Nil
public Node<T> myClone(){
return this;
}
On Vertex you want to do a deep clone (cloning the fields instead of just copying their references).
//On Vertex
public Node<T> myClone(){
return new Vertex<T>(head,left.myClone(),right.myClone())
}

Categories

Resources