I have Created Binary Search Tree by Using a Tree Interface and Recursion (I am aware that using a Node Class I can Implement the same ) providing methods for Adding and Checking if an element is in the Binary Search Tree or not.
The Problem I am facing is in instantiating & displaying the elements of the BST.
Here is my code
Tree Interface:
package bst;
public interface Tree<D extends Comparable>{
public boolean isempty();
public int cardinality();
public boolean member(D elt);
public NonEmptyBst<D> add(D elt);
}
EmptyBst Class:
package bst;
public class EmptyBst<D extends Comparable> implements Tree<D>{
public EmptyBst(){
D data=null;
}
#Override
public boolean isempty() {
// TODO Auto-generated method stub
return true;
}
#Override
public int cardinality() {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean member(D elt) {
// TODO Auto-generated method stub
return false;
}
#Override
public NonEmptyBst<D>add(D elt) {
// TODO Auto-generated method stub
return new NonEmptyBst<D>(elt);
}
}
NonEmptyBst Class
package bst;
public class NonEmptyBst<D extends Comparable> implements Tree<D> {
D data;
D root;
Tree<D> left;
Tree <D>right;
public NonEmptyBst(D elt){
data=elt;
root=elt;
left=new EmptyBst<D>();
right=new EmptyBst<D>();
}
NonEmptyBst(){
D dataThis=this.data;
}
public NonEmptyBst(D elt,Tree<D>leftTree,Tree<D>rightTree){
data=elt;
left=leftTree;
right=rightTree;
}
#Override
public boolean isempty() {
// TODO Auto-generated method stub
return false;
}
#Override
public int cardinality() {
// TODO Auto-generated method stub
return 1+left.cardinality()+right.cardinality();
}
public boolean member(D elt) {
if (data == elt) {
return true;
} else {
if (elt.compareTo(data) < 0) {
return left.member(elt);
} else {
return right.member(elt);
}
}
}
public NonEmptyBst<D> add(D elt) {
if (data == elt) {
return this;
} else {
if (elt.compareTo(data) < 0) {
return new NonEmptyBst(data, left.add(elt), right);
} else {
return new NonEmptyBst(data, left, right.add(elt));
}
}
}
}
BinarySearchTree Class
package bst;
import bst.Tree;
import bst.EmptyBst;
import bst.NonEmptyBst;
public class BinarySearchTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
NonEmptyBst abcd=new NonEmptyBst( "abc");
NonEmptyBst ab=new NonEmptyBst(67);
abcd.add("cry me a river");
abcd.add("geeehfvmfvf");
abcd.add("I'm Sexy and i know it");
abcd.add("zzzzsd");
abcd.add("zzzzsd");
abcd.add("zzzfdsf");
abcd.add("zzfedfrsd");
abcd.add("tgrgdzsd");
abcd.add("gtrgrtgtrgtrzzzzsd");
abcd.add("zzzzsd");
abcd.add("zdddzzzsd");
abcd.add("zzzzsd");
abcd.add("zzzzsd");
}
}
**
How Can I access the data at all nodes and then Print Them out?The Particular Problem I am facing is In Getting an exception namely ClassCastException when I access the "leaf Nodes" and even if I Initalize new NonEmptyBst<D>in My NonEmptyBst<D>(D elt) constructor I end Up having a null pointer Exception
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.compareTo(Unknown Source)
at java.lang.String.compareTo(Unknown Source)
at bst.NonEmptyBst.add(NonEmptyBst.java:51)
at bst.NonEmptyBst.add(NonEmptyBst.java:54)
at bst.BinarySearchTree.main(BinarySearchTree.java:11)
I'm not really sure I see the need for EmptyBst unless you are trying to follow the design-pattern for a Null Object.
Specifically, an "empty" tree can easily be checked if data == null && left == null && right == null. Also, no need for data here, since it is a local variable and never referenced.
public EmptyBst(){
D data=null;
}
And is there a difference between D data and D root?
I think you need to adjust your add method to capture the result of the recursion.
public NonEmptyBst<D> add(D elt) {
if (data == elt) {
return this;
} else {
if (elt.compareTo(data) < 0) {
this.left = this.left.add(elt);
} else {
this.right = this.right.add(elt);
}
}
return this;
}
You need to access it recursively. As I don't have your node implementation I'll write a general example:
// Return a list with all the nodes
public List<Node> preOrder() {
List<Node> l = new ArrayList<Node>();
l.add(this.value); // Add the data of the root
if(this.left != null) // Add elements to the left
l.addAll(this.left.preOrder());
if(this.right != null) // Add elements to the right
l.addAll(this.right.preOrder());
return l;
}
Then you would simply call it:
List<Node> nodes = myTree.preOrder();
And then loop through the list to do whatever you want.
Related
So i am building a library as project that covers not all but most of the data structures and i found myself with this problem:
package structure.tree;
import structure.Structure;
import structure.node.BinaryNodeKeyValue;
public class AVLTree<Comparable,V> extends Tree<BinaryNodeKeyValue<Comparable,V>> {
private static final long serialVersionUID = 5046115177325966348L;
public AVLTree(){
}
#Override
public int compareTo(Structure<BinaryNodeKeyValue<Comparable,V>> o) {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean containsValue(BinaryNodeKeyValue<Comparable,V> elem) {
return containsValueAux(((BinaryNodeKeyValue<Comparable,V>) super.getValue()), elem);
}
private boolean containsValueAux(BinaryNodeKeyValue<Comparable,V> root, BinaryNodeKeyValue<Comparable,V> elem){
if(root == null) return false;
else {
if(root.equals(elem)) return true;
else return containsValueAux(root.getLeft(), elem) || containsValueAux(root.getRight(), elem);
}
}
public boolean containsKey(Comparable key){
return containsKeyAux(((BinaryNodeKeyValue<Comparable,V>) super.getValue()), key);
}
private boolean containsKeyAux(BinaryNodeKeyValue<Comparable,V> root, Comparable key){
if(root == null) return false;
else {
if(root.getKey().compareTo(key) > 0) return containsKeyAux(root.getRight(), key);
else if(root.getKey().compareTo(key) < 0) return containsKeyAux(root.getLeft(), key);
else return true;
}
}
#Override
public void deleteValue(BinaryNodeKeyValue<Comparable,V> elem) {
// TODO Auto-generated method stub
}
#Override
public void insertValue(BinaryNodeKeyValue<Comparable,V> elem) {
// TODO Auto-generated method stub
}
#Override
public BinaryNodeKeyValue<Comparable,V>[] toArray() {
// TODO Auto-generated method stub
return null;
}
public BinaryNodeKeyValue<Comparable,V> get(BinaryNodeKeyValue<Comparable,V> root, Comparable key){
return getAux(root, key);
}
private BinaryNodeKeyValue<Comparable, V> getAux(BinaryNodeKeyValue<Comparable, V> root, Comparable key) {
return null;
}
}
At rows 40 and 41 (rows 3 and 4 of method containsKeyAux) it says "The method compareTo(Comparable) is undefined for the type Comparable" and this blows my mind cause the method compareTo is actually defined inside Comparable interface only.
VS Code is also showing me a warning at row 6 that says "The type parameter Comparable is hiding the type Comparable" but i am trying to make the Comparable type as generic as possible cause the key of nodes could be a String, Integer, or a different type of Object.
When you declare a generic like this AVLTree<Comparable,V> you have created a class with two generic types Comparable and V and Comparable has nothing to do with the interface Comparable, they just happen to have the same name.
You probably meant
class AVLTree<T extends Comparable, V>
I am having frustrating trouble getting my ArrayList to initialize. I am getting an error at the line binaryTreeList.set(1, root); saying
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.set(Unknown Source)
at BinaryTreeADT.<init>(BinaryTreeADT.java:18)
at Driver.main(Driver.java:7)
I'm trying to implement a simple binary tree using an ArrayList and I'd like the "root" element to be at ArrayList position 1. For some reason, the size of the `binaryTreeList is not growing, despite adding nodes to all of them.
Here is my code in order of Driver, BinaryTreeADT and MyTreeNode
public class Driver {
public static void main(String[] args) {
MyTreeNode mtn = new MyTreeNode(3, 'R');
BinaryTreeADT bt = new BinaryTreeADT(mtn);
bt.printTree();
}
}
BinaryTreeADT:
import java.util.ArrayList;
import javax.swing.tree.TreeNode;
public class BinaryTreeADT {
private ArrayList<MyTreeNode> binaryTreeList;
private MyTreeNode nullNode = new MyTreeNode(true); //This creates a null node that initially populates the array.
//Constructor with no root
public BinaryTreeADT(){
binaryTreeList = new ArrayList<MyTreeNode>(10);
}
public BinaryTreeADT(MyTreeNode root){
binaryTreeList = new ArrayList<MyTreeNode>(10);
initializeList();
binaryTreeList.set(1, root);
}
private void initializeList(){
for (int i = 0; i < binaryTreeList.size(); i++){
binaryTreeList.add(nullNode);
}
}
public void add(){
}
public void printTree(){
for (int i = 0; i < binaryTreeList.size(); i++){
if (binaryTreeList.get(i) != null)
System.out.println(binaryTreeList.get(i).getNodeChar() + " | ");
}
}
}
MyTreeNode:
import java.util.Enumeration;
import javax.swing.tree.TreeNode;
public class MyTreeNode implements TreeNode {
private int nodeKey;
private char nodeChar;
private boolean isNull;
public MyTreeNode(int key, char letter){
nodeKey = key;
nodeChar = letter;
}
//Constructor for Null Node
public MyTreeNode(boolean setNull){
isNull = setNull;
}
public boolean isNull(){ //Tells if this is a null node
return isNull;
}
#Override
public Enumeration children() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean getAllowsChildren() {
// TODO Auto-generated method stub
return false;
}
#Override
public TreeNode getChildAt(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int getChildCount() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getIndex(TreeNode arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public TreeNode getParent() {
// TODO Auto-generated method stub
return null;
}
public int getNodeKey() {
return nodeKey;
}
public void setNodeKey(int nodeKey) {
this.nodeKey = nodeKey;
}
public char getNodeChar() {
return nodeChar;
}
public void setNodeChar(char nodeChar) {
this.nodeChar = nodeChar;
}
#Override
public boolean isLeaf() {
// TODO Auto-generated method stub
return false;
}
}
Reason is this line:
binaryTreeList.set(1, root);
Because size of binaryTreeList is zero . You have constructed the ArrayList and told it to have the initial Capacity to be 10 using constructor ArrayList(int initialCapacity) , But since nothing is inside ArrayList right now , so ArrayList#size() is returning as 0. That's why within your initializeList method the for loop is exited at very first iteration which is not initializing the binaryTreeList with 10 elements. So the size of binaryTreeList is again still 0. This is the reason that setting a value at index 1 which is not existing at all is throwing IndexOutOfBoundException.
You should instead define initializeList as:
private void initializeList(){
for (int i = 0; i < 10; i++){
binaryTreeList.add(nullNode);
}
}
You are attempting to set the element at position 1 when your ArrayList is empty:
binaryTreeList.set(1, root);
Instead just use:
binaryTreeList.add(root);
Your reference is out of bounds. You should set the 0th index to your root node. However, since your ArrayList is empty (size = 0), you need to actually add the new element, which will increment the size of the array.
binaryTreeList.add(root);
With arrays, indices start at 0, so the element at index 0 of an array is the first element, the element at index 1 is the second, etc. If you have an array of size n, the last element will be at index n-1.
Later, if you want to change an element at a certain index, you can set the 0th element to root:
binaryTreeList.set(0, root);
This will work provided the first argument (0 in this case) is less than or equal to the binaryTreeList.size()-1.
I want to make LinkedList by Eclipse
but i don't know how to make LinkedList.
First of all, I want to compare with int's data and reference.
but, i don't know how to compare.
package List;
public class DoubleLinkedList
{
CellDouble x;
CellDouble head;//List's head
public DoubleLinkedList()
{
//리스트의 헤더를 할당한다.
head=new CellDouble(0);
head.prev=head.next=head;
}
public void insertAfter(CellDouble p,int data)
{
CellDouble x=new CellDouble(data);
x.prev=p;
x.next=p.next;
p.next.prev=x;
p.next=x;
}
public void insertFirst(int data)
{
//List's next to insert
insertAfter(head.next,data);
}
public void insertLast(int data)
{
//list's last's next to insert.
insertAfter(head.prev,data);
}
public void removeCell(CellDouble p)
{
p.prev.next=p.next;
p.next.prev=p.prev;
}
public Object removeFirst()
{
if(isEmpty())
{
return null;
}
CellDouble cell=head.next;
removeCell(cell);
return cell.data;
}
public Object removeLast()
{
// 요소가 없다면 null 반환
if(isEmpty())
{
return null;
}
CellDouble cell=head.prev;
removeCell(cell);
return cell.data;
}
public boolean isEmpty()
{
return head.next==head;
}
public void FindNumber(int data)
{
if(x==null)
{
insertFirst(data);
}
else if(x.data<data)
{
insertAfter(x,data);
}
}
public void Findnumber(int data)
{
if(x.data==data)
{
removeCell(x);
}
else if(x.data!=data)
{
System.out.println("like this number is nothing");
}
}
}
And, I finished my programming. but, its outcome 'List.DoubleLinkedList#8c1dd9'
Check my answer here for the basics. The elements of your list must implement Comparable, read more here.
I have a ContentProvider for a TreeSelectionDialog. I need to implement the getParent method in order to select the root of a tree if one of its nodes is checked. This is the code:
#SuppressWarnings("unchecked")
protected Node<T> getAdapter(Object element) {
if(element instanceof Tree)
return ((Tree<T>)element).getRootElement();
else
return (Node<T>)element;
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// TODO Auto-generated method stub
}
#Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
#Override
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof org.db.normalization.Table) {
if(((org.db.normalization.Table)parentElement).getStatus() == Status.DELETED)
return new Object[0];
List<org.db.normalization.Attribute> atts = new ArrayList<org.db.normalization.Attribute>();
for(Attribute a:((org.db.normalization.Table)parentElement).getAttributes().getAttributes())
if(a.getStatus() != Status.UNMODIFIED)
atts.add(a);
for(Attribute a:((org.db.normalization.Table)parentElement).getPrimaryKey().getAttributes())
if(a.getStatus() != Status.UNMODIFIED)
atts.add(a);
return atts.toArray();
} else if (parentElement instanceof org.db.normalization.Attribute) {
return new Object[0];
} else {
#SuppressWarnings("unchecked")
List<org.db.normalization.Table> n = (ArrayList<org.db.normalization.Table>)parentElement;
if (n.size() > 0) {
return n.toArray() ;
}
}
return new Object[0];
}
#Override
public Object getParent(Object element) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean hasChildren(Object element) {
// TODO Auto-generated method stub
return getChildren(element).length > 0;
}
I really have no idea of what to write in the getParent method, since I have no other information than the element received as a parameter, and this element alone, doesn't know its parent.
Thanks!
Most instances of a tree implementation, you do know your parent, so parents are either set by a setter method or on the constructor. You have no idea who the parent is, so you are presenting the worse case, where you basically have to get all node, and check rather the children of each node contain you.
Queue12 is an interface, QueueImp12 is an implementation of Queue12. So i'm trying to test my QueueImp12 but when i run it(it compiles) in eclipse my output gets terminated in console. I believe I created ringBuffer correctly. If my test looks fine, then something must be wrong with my implementation or eclipse. Thanks
import java.util.NoSuchElementException;
public class QueueImpl12<T> implements Queue12<T>
{
private int _size, _backIdx, _frontIdx;
private static final int _defaultCapacity = 128;
private T[] _ringBuffer;
public QueueImpl12(int capacity)
{
_ringBuffer = (T[]) new Object[capacity];
clear();
}
public QueueImpl12()
{
_ringBuffer = (T[]) new Object[_defaultCapacity];
clear();
}
private int wrapIdx(int index)
{
return index % capacity();
}
public void clear()
{
_backIdx = 0;
_frontIdx = 0;
_size = 0;
}
#Override
public int capacity()
{
// TODO Auto-generated method stub
return _ringBuffer.length;
}
#Override
public int size()
{
// TODO Auto-generated method stub
return _size;
}
#Override
public boolean enqueue(T o)
{
//add o to back of queue
if(_ringBuffer.length == _size)
{
return false;
}
_ringBuffer[_backIdx] = o;
_backIdx = wrapIdx(_backIdx + 1 );
_size++;
return true;
}
#Override
public T dequeue()
{
if(_size == 0) //empty list
{
throw new NoSuchElementException();
}
T tempObj = _ringBuffer[_frontIdx]; //store frontIdx object
_ringBuffer[_frontIdx] = null;
_frontIdx++;
_size--;
return tempObj;
}
#Override
public T peek()
{
return _ringBuffer[_frontIdx];
}
}
public class P3test
{
public static<T> void main(String[] args)
{
final Queue12<T> ringBuffer = new QueueImpl12<T>();
T o = (T) new String("this");
ringBuffer.enqueue(o); //add element to the back
ringBuffer.dequeue(); //remove/return element in the front
}
}
That 'terminated' you have been seeing lately is the expected behavior when your program finishes.
Put some System.outs or asserts to verify that your code runs (here it runs, with some awful cast warnings, but runs)
final Queue12<T> ringBuffer = new QueueImpl12<T>();
T o = (T) new String("this");
ringBuffer.enqueue(o); //add element to the back
System.out.println(ringBuffer.peek());//this should print 'this' in the console\
//assertEquals('this', ringBuffer.peek());
ringBuffer.dequeue(); //remove/return element in the front
Learn how to use generics and tests. And don't put generic argument in main function, is is useless there.