Hello I would like to know how to set up an object oriented BST class that has a private Node class.(Both classes being generic)
so far I have this but i am having some compilation errors. Some explanation would be nice. I copied this code, but I know there are mistakes to fix. Also how would you set up the constructor of the bst?
#SuppressWarnings("unchecked")
//public class BinarySearchTree<T extends Comparable<? super T>> {
public class BST<T extends Comparable<T>> implements Iterable<T>
{
private Node <T> root;
// public BST(){
// root=null;
// }
private T search(T target, BST <T> p)
{
int comp=target.compareTo(p.data);
T c=target.compareTo(P.data);
if(comp==0)
return c;
}
private class Node<T extends Comparable<T>> implements Iterable {
T data;
Node<T> left, right;
public Node(T t)
{
data=t;
}
#Override
public Iterator iterator() {
// TODO Auto-generated method stub
return null;
}
public T search(T target)
{
return search(target, root);
}
}
#Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return null;
}
}
The default constructor should be fine that you've originally commented out should be fine. Is there a particular use case you have in mind that it doesn't satisfy?
Something like this. Because the Node class is a private inner class, it doesn't have to be generic and can instead use the type specified in its parent class, which is what I assume you want anyway.
The node class doesn't really need a search method because it only contains one value. There's no need to search if there's just one value. This is also the same reason it doesn't need a iterator either. There's really no need to iterate over just one value.
When designing an abstract data type such as a BST, it's good to consider how you envision it will be used: what operations should it support, aka. its API. The implementation below supports 2 operations: insert and search. Possible extensions might include a remove and/or a contains operation.
Operations on a tree are typically recursive. This is because you start at the root and have to traverse through inner nodes which themselves can be viewed as roots of their respective subtrees. Try walking through a few example inserts and searches to convince yourself why it works that way.
import java.util.Iterator;
public class BST<T extends Comparable<T>> implements Iterable<T> {
private Node root;
public BST(){
root=null;
}
private void insertInternal(T value, Node parent) {
int comp=value.compareTo(parent.data);
if(comp < 0) {
if(parent.left == null) {
parent.left = new Node(value);
}
else {
insertInternal(value, parent.left);
}
}
else if(comp > 0) {
if(parent.right == null) {
parent.right = new Node(value);
}
else {
insertInternal(value, parent.right);
}
}
}
public void insert(T value) {
if(root == null) {
root = new Node(value);
return;
}
insertInternal(value, root);
}
private Node searchInternal(T target, Node node) {
if(node == null) {
return null;
}
int comp=target.compareTo(node.data);
if(comp < 0) {
return searchInternal(target, node.left);
}
else if(comp > 0) {
return searchInternal(target, node.right);
}
return node;
}
public Node search(T target) {
return searchInternal(target, root);
}
private class Node {
T data;
Node left, right;
public Node(T t) {
data=t;
}
}
#Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return null;
}
public static void main(String[] args) {
BST<Integer> bst = new BST<Integer>();
bst.insert(2);
bst.insert(6);
System.out.println(bst.search(2) != null);
System.out.println(bst.search(6) != null);
System.out.println(bst.search(8) == null);
}
}
Related
I can't write correctly function that deletes one node from tree. If this node has children, they should move one level higher. Children of deleted element will have parent of deleted elem,ancestors will they on they places, but one level higher. How can I do it right?
import java.util.ArrayList;
import java.util.List;
public class Node<T> {
private T value;
private final List<Node<T>> listOfChildren;
private Node<T> parent;
public Node(){
super();
listOfChildren = new ArrayList<>();
}
public Node(T value){
this();
setValue(value);
}
public T getValue() {
return value;
}
public void setParent(Node<T> parent) {
this.parent = parent;
}
public List<Node<T>> getListOfChildren() {
return listOfChildren;
}
public void setValue(T value) {
this.value = value;
}
public int getNumberOfChildren() {
return listOfChildren.size();
}
public void addChildren(Node<T> child) {
parent = this;
listOfChildren.add(child);
}
public void removeChildAt(int index) {
if (index > listOfChildren.size()-1){
throw new IndexOutOfBoundsException( "This index is too big");
}
else {
Node<T> element = this.listOfChildren.get(index);
if (element.listOfChildren.size() > 0) {
// function...
}
listOfChildren.remove(index);
}
}
}
I think that writing dfs or bfs to walk through the tree is not the best way to realize this function. What is the best way to realize this function?
Children of deleted element will keep their descendants, so no walk through required
public void removeChildAt(int index) throws IndexOutOfBoundsException {
if (listOfChildren != null) {
Node<T> element = this.listOfChildren.get(index);
if (element.listOfChildren.size() > 0) {
this.listOfChildren.addAll(element.listOfChildren);
//element.listOfChildren.forEach(child -> child.setParent(this)); but you have no backward reference to parent
}
listOfChildren.remove(index);
}
else {
System.out.println("No children from this node");
}
}
For this assignment I need to create a linked stack class that contains a getMin() and getMax(). I cannot change the class header which was provided by the instructor. Both getMin and getMax should be O(1) time.
My thought is that I need to use the compareTo method to compare entries as they are pushed or poped so that I can set variables minValue and maxValue equal to their respective values. However, I don't understand the section in the class header <T extends Comparable<? super T>> nor do I know how or where to implement Comparable. I tried having my class Node<E> implement Comparable but it asked me to override the compareTo method and I'm not sure how that would work.
Any help would be greatly appreciated! Below is my code for this assignment:
public class MinMaxStack <T extends Comparable<? super T>> implements StackADT<T> {
private Node<T> top;
private int size;
public MinMaxStack() {
clear();
}
private class Node<E>{
E data;
Node<E> previous;
}
public T getMin() {
if(isEmpty()) {
throw new EmptyCollectionException("The stack is empty but is trying to getMin.");
} else {
return null;
}
}
public T getMax() {
return null;
}
#Override
public T pop() {
if(isEmpty()) {
throw new EmptyStackException("Stack is empty but trying to pop.");
}else {
T dataToReturn = top.data;
top = top.previous;
size -= 1;
return dataToReturn;
}
}
#Override
public T peek() {
if(isEmpty()) {
throw new EmptyStackException("Stack is empty but trying to peek");
}else {
return top.data;
}
}
#Override
public void push(T newItem) {
Node<T> newNode = new Node<>();
newNode.data = newItem;
if(!isEmpty()) {
newNode.previous = top;
}
top = newNode;
size += 1;
}
#Override
public int getSize() {
return size;
}
#Override
public void clear() {
while(!isEmpty()) {
top = null;
size = 0;
}
}
#Override
public boolean isEmpty() {
return size == 0;
}
}
package einfuehrung.knodenUndListeKopie;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class List<T> {
private class ListIterator<K> implements Iterator<T> {
private Node<T> node = null;
public ListIterator() {
node = head;
}
#Override
public boolean hasNext() {
return node.getNext() != null;
}
#Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
node = node.getNext();
T obj = node.getObject();
return obj;
}
}
public Iterator<T> iterator() {
ListIterator<T> iter = new ListIterator<T>();
return iter;
}
private Node<T> head;
public List() {
this.head = new Node<T>();
}
public Node<T> getHead() {
return head;
}
public void setHead(Node<T> head) {
this.head = head;
}
public boolean isEmpty() {
return head.getNext() == null;
}
public void addFirst(T element) {
Node<T> node = new Node<T>();
Node<T> nextNode = head.getNext();
node.setObject(element);
node.setNext(nextNode);
head.setNext(node);
}
public void addLast(T element) {
Node<T> node = new Node<T>();
Node<T> lastNode = head;
while (lastNode.getNext() != null) {
lastNode = lastNode.getNext();
}
lastNode.setNext(node);
node.setNext(null);
node.setObject(element);
}
public Object removeFirst() {
Object solution;
if (isEmpty()) {
solution = null;
}
Node<T> node = head.getNext();
Node<T> nextNode = node.getNext();
solution = node.getObject();
head.setNext(nextNode);
return solution;
}
public Object removeLast() {
Object solution;
if (isEmpty()) {
solution = null;
}
Node<T> beforeLastNode = head;
Node<T> lastNode;
while (beforeLastNode.getNext().getNext() != null) {
beforeLastNode = beforeLastNode.getNext();
}
lastNode = beforeLastNode.getNext();
solution = lastNode.getObject();
beforeLastNode.setNext(null);
return solution;
}
/**
* It does not delete the node, where the element is saved.
*
* #return first element of list
*/
public Object getFirstElement() {
return head.getNext().getObject();
}
}
First above is my List-Class.
package einfuehrung.knodenUndListeKopie;
import java.util.Collection;
public class Node<T extends Collection<?>> {
private Node<T> next;
private T object;
public Node() {
}
public Node(Node<T> next, T object) {
this.next = next;
this.object = object;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
public T getObject() {
return object;
}
public void setObject(T object) {
this.object = object;
}
public int countAllElements() {
int solution;
solution = object.size();
if (this.next != null) {
solution += this.next.countAllElements();
}
return solution;
}
}
Second Class is my Node-Class.
Problem Description. Everything was fine after i restricted the Parameter T in my Node Class. I had to, because T needed to implement the size-Method. It was necessary for the countAllElements() Method in Node-Class. In my List Class i get the error message : "Type T is not a valide Substitute for the bounded Parameter <T extends Collection<?>> of the type Node<T>. The error message appears everywhere where i use an instance of my object from the type Node<T>.
I hope i did everything Right in this Question by Posting my Code here. Sorry for my case-shift, i live in Germany. I dont know what my Computer does D:.
Edited: Sorry guys, i forgot to Change the title. I adjusted it.
As it stands, you are contradicting yourself: you are saying that your Nodes can contain any T in your List class, but your Node class says they can contain any Collection.
So, you either need to:
Go through all of the Node<T>s in the List class, replacing them with something list Node<Collection<T>>, Node<List<T>> etc
Remove the bound on the type parameter in the Node class, and supply a ToIntFunction<? super T> to the countAllElements method, to allow you to say "this is how you 'count' a T":
public int countAllElements(ToIntFunction<? super T> counter) {
int solution = counter.apply(object);
if (this.next != null) {
solution += this.next.countAllElements(counter);
}
return solution;
}
I have to create a node class that is sorted alphabetically, so I think that it is a single-linked list. I am supposed to create it "recursively" and I am confused with this. I have to implement basic methods to query the list, which are easy enough but I'm stuck on the initializing part and especially adding nodes.
Any help?
My code looks like this right now :
public class SortedSetNode implements Set {
protected String value;
protected SortedSetNode next;
public SortedSetNode(String v, SortedSetNode n) {
//value = v;
//next = n;
}
public SortedSetNode(String v) {
//value = v;
}
}
This is how I would implements a sorted list. Note: a list is not a set.
public class SortedList<E extends Comparable<E>> {
private SortedNode<E> head = null;
public void add(E e) {
SortedNode<E> node = new SortedNode<E>(e);
if (head == null || head.e.compareTo(e) <= 0) {
node.next = head;
head = node;
} else {
head.add(node);
}
}
}
public class SortedNode<E extends Comparable<E>> {
final E e;
SortedNode<E> next;
public SortedNode(E e) {
this.e = e;
}
public void add(SortedNode<E> node) {
if (next == null || e.compareTo(node.e) <= 0) {
node.next = next;
next = node;
return;
}
next.add(node);
}
}
these are my fields:
public class BSTSet <E> extends AbstractSet <E> {
// Data fields
private BSTNode root;
private int count = 0;
private Comparator<E> comp; // default comparator
/** Private class for the nodes.
* Has public fields so methods in BSTSet can access fields directly.
*/
private class BSTNode {
// Data fields
public E value;
public BSTNode left = null;
public BSTNode right = null;
// Constructor
public BSTNode(E v) {
value = v;
}
//creates a method called contains so that i can call it later on for my find method
public boolean contains(Object item) {
return contains(item);//root.value.equals(item);
}
public int height() {
return height();
}
}
// Constructors - can either use a default comparator or provide one
public BSTSet() {
comp = new ComparableComparator(); // Declared below
}
public BSTSet(Comparator <E> c) {
comp = c;
}
}
and this is what i am trying to complete:
private class BSTSetIterator implements Iterator<E> {
private Stack<BSTNode> stack = new Stack<BSTNode>();
private BSTNode current = root;
public BSTSetIterator(BSTNode root) {
return new BSTSetIterator();
}
public boolean hasNext() {
boolean hasNext = false;
hasNext = !stack.isEmpty() || current != null;
return hasNext;
}
public E next() {
BSTNode next = null;
while (current != null) {
stack.push(current);
current = current.left;
}
next = stack.pop();
current = next.right;
return next;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
// Comparator for comparable
private class ComparableComparator implements Comparator<E> {
public int compare(E ob1, E ob2) {
return ((Comparable)ob1).compareTo(ob2);
}
}
So far the code fails at lines return new BSTSetIterator(); and return next;. For return next it says that it is the wrong data type to return. How would I go about fixing these methods so that I can iterate through a BST using a Stack?
BSTSetIterator();
This doesn't work, because your constructor expects a root and you didn't pass that parameter. If you have a BSTSet object called 'tree', and you want to create a new iterator, then you should create the iterator this way:
BSTSetIterator iterator = new BSTSetIterator(tree.getRoot());
However, you don't have a getter in your BSTSet class and your root is private. Don't worry, the solution for that problem is to create a public getter inside your BSTSetIterator class, like this:
public BSTNode getRoot()
{
return this.root;
}
Constructors don't return values, this is incorrect:
public BSTSetIterator(BSTNode root) {
return new BSTSetIterator();
}
Instead, write your construtor this way:
public BSTSetIterator(BSTNode root)
{
this.current = root;
}
Also, this definition is incorrect, because root is out of reach:
private BSTNode current = root;
You should have this instead:
private BSTNode current;
As for your other problem,
BSTNode next = null;
means that your variable called 'next' is of BSTNode type.
public E next()
means that your method called next is of E type. as E and BSTNode is not the same, your return:
return next;
is incorrect. I could give you more help, but I have realized you are learning now the language and it's better to let you explore yourself the technology and programming in general, because this way you will become quicker. "Give a man a fish, and you feed him for a day. Teach a man how to fish, and you feed him for a lifetime."