im trying to make a linked list of generic objects. i have the linked list made now i have to load a file of movies(in movie class i have genre,rating, title).first i need to load a CVS file of movies the create Hash Table Object which contains an array of Linked List objects which in turn stores the Movies. so for example in a movie class i will have genre and genre can be many. i want to get hash code of genre and then store that in a hash table of arrayed linked list. that's what im using the LoadingMovie class for.
i dont know what im doing as it my first time working with hash tables and link list etc.this is what i have so far:
public class List<T> {
private Node<T> head;
private Node<T> tail;
private int count;
public void append(T d) {
if (head == null) {
head = tail = new Node<T>(d);
} else {
tail.insertAfter(d);
tail = tail.getNext();
count++;
}
}
public void prepend(T d) {
if (head == null) {
head = tail = new Node<T>(d);
} else {
head.insertBefore(d);
head = head.getPrevious();
count++;
}
}
public void removeHead() {
if (head == null) {
return;
} else if (head == tail) {
head = tail = null;
count--;
return;
}
head = head.getNext();
count--;
}
public ListIterator<T> getIterator() {
return new ListIterator<T>(this, head);
}
public void add(ListIterator<T> iter, T data) {
if (iter.getList() != this) {
return;
}
if (!iter.isValid()) {
append(data);
} else {
iter.getCurrentNode().insertAfter(data);
count++;
if (iter.getCurrentNode() == tail) {
tail = iter.getCurrentNode().getNext();
}
}
}
public void remove(ListIterator<T> iter) {
if (iter.getList() != this) {
return;
}
Node<T> node = iter.getCurrentNode();
if (node == null) {
return;
} else if (node == head) {
removeHead();
} else if (node == tail) {
removeTail();
} else {
Node<T> ptn = node.getPrevious();
ptn.setNext(node.getNext());
node.getNext().setPrevious(ptn);
iter.advance();
count--;
}
}
public void removeTail() {
if (head == null) {
} else if (head == tail) {
head = tail = null;
count--;
} else {
Node<T> node = head;
while (node.getNext() != tail) {
node = node.getNext();
}
tail = node;
tail.setNext(null);
count--;
}
}
public void display() {
ListIterator<T> iter = getIterator();
do {
System.out.println(iter.item()+ " , ");
iter.advance();
} while (iter.isValid());
}
public void displayReverse() {
ListIterator<T> iter = getIterator();
iter.end();
do {
System.out.print(iter.item() + " , ");
iter.previous();
} while (iter.isValid());
}
public Node<T> getHead() {
return head;
}
public Node<T> getTail() {
return tail;
}
public int getCount() {
return count;
}
public void setHead(Node<T> head) {
this.head = head;
}
public void setTail(Node<T> tail) {
this.tail = tail;
}
public void setCount(int count) {
this.count = count;
}
#Override
public int hashCode() {
int hash = 5;
hash = 89 * hash + Objects.hashCode(this.head);
hash = 89 * hash + Objects.hashCode(this.tail);
hash = 89 * hash + this.count;
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final List<?> other = (List<?>) obj;
if (!Objects.equals(this.head, other.head)) {
return false;
}
if (!Objects.equals(this.tail, other.tail)) {
return false;
}
if (this.count != other.count) {
return false;
}
return true;
}
this is the node class :
public class Node<T> {
T anElement;
Node<T> next;
Node<T> previous;
public Node() {
anElement = null;
next = null;
}
public Node(T elem) {
anElement = elem;
next = null;
}
public T getAnElement() {
return anElement;
}
public void setAnElement(T anElement) {
this.anElement = anElement;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> getPrevious() {
return previous;
}
public void setPrevious(Node<T> previous) {
this.previous = previous;
}
#Override
public String toString() {
return "MyNode{" + "anElement=" + anElement + ", next=" + next + '}';
}
public void insertAfter(T nextData) {
if (nextData == null) {
return;
}
Node s = new Node(nextData);
s.setNext(next);
s.setPrevious(this);
if (next != null) {
next.setPrevious(s);
}
next = s;
}
public void insertBefore(T data) {
if (data == null) {
return;
}
Node s = new Node(data);
s.setNext(this);
s.setPrevious(previous);
if (previous != null) {
previous.setNext(s);
}
previous = s;
}
}
this is the load file class :
public class LoadingMovies {
private static final int size = 127;
private static HashMap<String, Movies> hash = new HashMap(size);
public static void loadMovies(String filename) {
String split = ","; //split with comma
try {
Scanner in = new Scanner(new File(filename));
String wordIn;
//List<Movies> linked = new List<>();
while (in.hasNextLine()) {
wordIn = in.nextLine();
String splitter[] = wordIn.split(split);
String movieTitle = splitter[0];
String movieGenre = splitter[1];
String ageRating = splitter[2];
double scoreRating = Double.parseDouble(splitter[3]);
Movies movie = new Movies();
movie.setTitle(movieTitle);
movie.setGenre(movieGenre);
movie.setAgeRating(ageRating);
movie.setScoreRating(scoreRating);
hash.find(movie.getGenre());
hash.insert(movie.getGenre(), movie);
hash.display();
}
} catch (FileNotFoundException e) {
System.out.println("Exception occured in the loadMovies() method in the Loadingovies class");
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String filename = input.next();
loadMovies(filename);
}
this is the hash map method:
public class HashMap<KeyType,DataType>
{
private int count;
private int size;
private List<HashEntry<KeyType,DataType>> [] table;
public HashMap() {
}
public HashMap(int num)
{
size = num;
table = new List[num];
for(int i = 0; i < num; i++){
table[i] = new List<HashEntry<KeyType,DataType>>();
}
}
public void insert(KeyType key, DataType data){
if(key != null && data != null){
int hash = key.hashCode() % size;
HashEntry<KeyType, DataType> obj = new HashEntry(key, data);
table[hash].append(obj);
count++;
}
}
public void display(){
for(int i = 0 ; i < size; i++){
System.out.println("tables" + i + " ");
table[i].display();
}
}
public DataType find(KeyType key){
int hash = key.hashCode() % size;
List<HashEntry<KeyType,DataType>> list = table[hash];
ListIterator <HashEntry<KeyType, DataType>> iter = list.getIterator();
while(iter.isValid()){
if(iter.item().getKey().equals(key)){
return iter.item().getData();
}
iter.advance();
}
return null;
}
public void remove(KeyType key){
int hash = key.hashCode() % size;
List<HashEntry<KeyType,DataType>> list = table[hash];
ListIterator <HashEntry<KeyType, DataType>> iter = list.getIterator();
while(iter.isValid()){
if(iter.item().getKey().equals(key)){
list.remove(iter);
}
iter.advance();
}
}
}
and this is what i have for movie class:
public class Movies {
private String title;
private String genre;
private String ageRating;
private double scoreRating;
public Movies() {
title = "";
genre = "";
ageRating = "";
scoreRating = 0;
}
public Movies(String title, String genre, String ageRating, double scoreRating) {
this.title = title;
this.genre = genre;
this.ageRating = ageRating;
this.scoreRating = scoreRating;
}
public String getTitle() {
return title;
}
public String getGenre() {
return genre;
}
public String getAgeRating() {
return ageRating;
}
public double getScoreRating() {
return scoreRating;
}
public void setTitle(String title) {
this.title = title;
}
public void setGenre(String genre) {
this.genre = genre;
}
public void setAgeRating(String ageRating) {
this.ageRating = ageRating;
}
public void setScoreRating(double scoreRating) {
this.scoreRating = scoreRating;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Movies other = (Movies) obj;
if (!Objects.equals(this.title, other.title)) {
return false;
}
if (!Objects.equals(this.genre, other.genre)) {
return false;
}
if (!Objects.equals(this.ageRating, other.ageRating)) {
return false;
}
if (Double.doubleToLongBits(this.scoreRating) != Double.doubleToLongBits(other.scoreRating)) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 11;
hash = (int) ((hash * 10) + scoreRating);
if (this.title != null) {
hash = (hash * 10) + title.hashCode();
}
if (this.genre != null) {
hash = (hash * 10) + genre.hashCode();
}
if (this.ageRating != null) {
hash = (hash * 10) + ageRating.hashCode();
}
return hash;
}
#Override
public String toString() {
String statement = "Movie Title:" + title + "\n" + "Movie Genre:" + genre + "\n" + "Age Rating: " + ageRating + "\n" + "User Score: " + scoreRating + "\n";
return statement;
}
what am i doing wrong please :(
i get null pointer exceptions arrayoutofboundexceptions
some movies printing and i get loads of tables thatare null :'(
The problem here is in mapping objects to buckets. This line of code...
int hash = key.hashCode() % size;
is capable of producing a negative value. key.hashCode() can be a negative number, and the result of the % operator on a negative number is a negative number. That's what causes your ArrayIndexOutOfBounds exception. The simplest solution is to use the absolute value of the hashCode...
int hash = Math.abs(key.hashCode()) % size;
Related
I'm currently struggling to write a union() method for my AVL (auto balancing) tree IntegerSet Class.
Some requirements for my class:
Integer sets are ordered
Methods must be at most O(NlogN) time
You may not use a built in tree Java library. You must implement your own tree
The union() method: This is the mathematical union on two sets which creates a new set that contains all the elements from both sets. For example, [1, 2, 3] U [2, 3, 5, 6] results in a new set [1, 2, 3, 5, 6].
My thought was to copy the unique elements of each tree into an array, then use my constructor to create a new tree from that array. However, I haven't been able to copy the elements into an array correctly. I'm also wondering if there's a better way to be doing this.
My current code is below:
package dataStructures.AVL;
import java.util.LinkedList;
import java.util.Queue;
public class IntegerSet {
private Node root;
private int size;
public IntegerSet() {
clear();
}
public IntegerSet(int array[]) {
// Add elements of array to Binary Search Tree
for (int i = 0; i < array.length; i++) {
add(array[i]);
}
}
public int magnitude() {
return size;
}
public void clear() {
root = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public boolean add(int newItem) {
boolean added = false;
if (isEmpty()) {
root = new Node(newItem);
size += 1;
added = true;
} else {
added = add(null, root, newItem);
}
return added;
}
private boolean add(Node parent, Node current, int data) {
boolean added = false;
if (current == null) {
int result = data - parent.data; // data.compareTo(parent.data);
if (result < 0) {
parent.leftChild = new Node(data);
} else {
parent.rightChild = new Node(data);
}
size += 1;
return true;
} else if ((data - current.data) < 0) { // (data.compareTo(current.data) < 0) {
added = add(current, current.leftChild, data);
} else if (data - current.data > 0) { // (data.compareTo(current.data) > 0) {
added = add(current, current.rightChild, data);
} else {
return false;
}
fixHeight(current);
if (added) {
rebalance(parent, current);
}
return added;
}
public boolean remove(int itemToRemove) {
if (isEmpty()) {
return false;
} else if (size == 1 && root.data == itemToRemove) { // (size == 1 && root.data.equals(itemToRemove)) {
clear();
return true;
} else if (removeTraversal(null, root, itemToRemove)) {
size -= 1;
return true;
} else {
return false;
}
}
private boolean removeTraversal(Node parent, Node current, int data) {
boolean removed = true;
if (current == null) {
return false;
} else if (data - current.data < 0) { // (data.compareTo(current.data) < 0) {
removed = removeTraversal(current, current.leftChild, data);
} else if (data - current.data > 0) { // (data.compareTo(current.data) > 0) {
removed = removeTraversal(current, current.rightChild, data);
} else {
removeNode(parent, current);
}
fixHeight(current);
if (removed) {
rebalance(parent, current);
}
return removed;
}
private void removeNode(Node parent, Node current) {
if (current.leftChild == null && current.rightChild == null) {
// Remove leaf node
removeCase1(parent, current);
} else if (current.leftChild != null && current.rightChild == null) {
// Remove node with no right child
removeCase2(parent, current);
} else if (current.leftChild == null && current.rightChild != null) {
// Remove node with no left child
removeCase3(parent, current);
} else {
// Remove node with both children
removeCase4(parent, current);
}
fixHeight(parent);
}
private void removeCase1(Node parent, Node current) {
if (parent == null) {
root = null;
} else if (parent.leftChild == current) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
}
private void removeCase2(Node parent, Node current) {
if (parent == null) {
root = root.leftChild;
} else if (parent.leftChild == current) {
parent.leftChild = current.leftChild;
} else {
parent.rightChild = current.leftChild;
}
current.leftChild = null;
}
private void removeCase3(Node parent, Node current) {
if (parent == null) {
root = root.rightChild;
} else if (parent.leftChild == current) {
parent.leftChild = current.rightChild;
} else {
parent.rightChild = current.rightChild;
}
current.rightChild = null;
}
private void removeCase4(Node parent, Node current) {
Node leftMost = current.rightChild;
Node leftMostParent = current;
while (leftMost.leftChild != null) {
leftMostParent = leftMost;
leftMost = leftMost.leftChild;
}
current.data = leftMost.data;
removeNode(leftMostParent, leftMost);
rebalance(current, current.rightChild);
}
public boolean contains(int itemToFind) {
if (isEmpty()) {
return false;
} else {
Node temp = root;
while (temp != null) {
int result = itemToFind - temp.data;
if (result < 0) {
temp = temp.leftChild;
} else if (result > 0) {
temp = temp.rightChild;
} else {
return true;
}
}
}
return false;
}
public IntegerSet union(IntegerSet other) {
return null;
}
public IntegerSet intersection(IntegerSet other) {
return null;
}
public IntegerSet difference(IntegerSet other) {
return null;
}
public IntegerSet symmetricDifference(IntegerSet other) {
return null;
}
public int getMin() {
if (isEmpty()) {
throw new EmptyCollectionException("Cannot remove from an empty tree.");
} else {
Node temp = root;
while (temp.leftChild != null) {
temp = temp.leftChild;
}
return temp.data;
}
}
public int getMax() {
if (isEmpty()) {
throw new EmptyCollectionException("Cannot remove from an empty tree.");
} else {
Node temp = root;
while (temp.rightChild != null) {
temp = temp.rightChild;
}
return temp.data;
}
}
public int getHeight() {
return getHeight(root);
}
private int getHeight(Node node) {
if (node == null) {
return -1;
}
return Math.max(node.leftHeight, node.rightHeight);
}
private void fixHeight(Node node) {
if (node != null) {
node.leftHeight = getHeight(node.leftChild) + 1;
node.rightHeight = getHeight(node.rightChild) + 1;
}
}
private int balance(Node node) {
// If the balance > 1 imbalance is in left subtree
// If the balance < -1 imbalance is in right subtree
return node.leftHeight - node.rightHeight;
}
private Node rightRotation(Node n) {
Node c = n.leftChild;
Node t2 = c.rightChild;
c.rightChild = n;
n.leftChild = t2;
fixHeight(n);
fixHeight(c);
return c;
}
private Node leftRotation(Node n) {
Node c = n.rightChild;
Node t2 = c.leftChild;
c.leftChild = n;
n.rightChild = t2;
fixHeight(n);
fixHeight(c);
return c;
}
private void rebalance(Node parent, Node node) {
if (node == null) {
return;
}
// Imbalance in left subtree
if (balance(node) > 1) {
// Handles case III
if (balance(node.leftChild) < 0) {
// leftRotation
node.leftChild = leftRotation(node.leftChild);
}
if (parent == null) {
root = rightRotation(node);
} else if (parent.leftChild == node) {
parent.leftChild = rightRotation(node);
} else {
parent.rightChild = rightRotation(node);
}
// Imbalance in right subtree
} else if (balance(node) < -1) {
// Handle case IV
if (balance(node.rightChild) > 0) {
node.rightChild = rightRotation(node.rightChild);
}
if (parent == null) {
root = leftRotation(node);
} else if (parent.leftChild == node) {
parent.leftChild = leftRotation(node);
} else {
parent.rightChild = leftRotation(node);
}
}
}
#Override
public String toString() {
return levelOrderString();
}
public String levelOrderString() {
StringBuffer sb = new StringBuffer();
sb.append("{");
if (!isEmpty()) {
Queue<Node> q = new LinkedList<>();
q.add(root);
Node current = null;
while (!q.isEmpty()) {
current = q.remove();
if (current.leftChild != null) {
q.add(current.leftChild);
}
if (current.rightChild != null) {
q.add(current.rightChild);
}
sb.append(current);
if (!q.isEmpty()) {
sb.append(", ");
}
}
}
sb.append("}");
return sb.toString();
}
public String inOrderToString() {
StringBuffer sb = new StringBuffer();
sb.append("{ ");
inOrderToString(root, sb);
sb.append(" }");
return sb.toString();
}
private void inOrderToString(Node current, StringBuffer sb) {
if (current != null) {
inOrderToString(current.leftChild, sb);
if (current.leftChild != null) {
sb.append(", ");
}
sb.append(current.data);
if (current.rightChild != null) {
sb.append(", ");
}
inOrderToString(current.rightChild, sb);
}
}
// You may add any methods or constructors
// to this class that you see fit.
private class Node {
private int data;
private Node leftChild;
private Node rightChild;
private int leftHeight;
private int rightHeight;
public Node(int data) {
this.data = data;
}
public String toString() {
String formatter = "(%s | %s | %s)";
String leftString = leftChild != null ? Integer.toString(leftChild.data) : "";
String rightString = rightChild != null ? Integer.toString(rightChild.data) : "";
return String.format(formatter, Integer.toString(data), leftString, rightString);
}
}
}
I am learning about Binary Search Tree and working on a project. When I tried to delete the first node I inserted, it doesn't delete and still show that node when I call showAll method. Is that how Binary Search Tree works or did I do something incorrectly?
Thanks,
Here is the code for BinarySearchTree class:
public class BinarySearchTree_Pham {
TreeNode root;
public BinarySearchTree_Pham() {
root = null;
}
public boolean insert(Student_Pham newStudent) {
TreeNodeWrapper p = new TreeNodeWrapper();
TreeNodeWrapper c = new TreeNodeWrapper();
TreeNode n = new TreeNode();
if(n == null)
return false;
else {
n.node = newStudent.deepCopy();
n.lc = null;
n.rc = null;
if(root == null) {
root = n;
}
else {
findNode(newStudent.getId(), p, c);
if(newStudent.getId().compareTo(p.get().node.getId()) < 0)
p.get().lc = n;
else
p.get().rc = n;
}
return true;
}
} //end insert
public Student_Pham fetch(String id) {
boolean found;
TreeNodeWrapper p = new TreeNodeWrapper();
TreeNodeWrapper c = new TreeNodeWrapper();
found = findNode(id, p, c);
if (found == true)
return c.get().node.deepCopy();
else
return null;
} //end fetch
public boolean delete(String id) {
boolean found;
TreeNodeWrapper p = new TreeNodeWrapper();
TreeNodeWrapper c = new TreeNodeWrapper();
TreeNode largest;
TreeNode nextLargest;
found = findNode(id, p, c);
if(found == false)
return false;
else {
if(c.get().lc == null && c.get().rc == null) {
if (p.get().lc == c.get())
p.get().lc = null;
else
p.get().rc = null;
} //end case 1
else if (c.get().lc == null || c.get().rc == null) {
if (p.get().lc == c.get()) {
if (c.get().lc != null)
p.get().lc = c.get().lc;
else
p.get().lc = c.get().rc;
}
else {
if (c.get().lc != null)
p.get().rc = c.get().lc;
else
p.get().rc = c.get().rc;
}
} // end case 2
else {
nextLargest = c.get().lc;
largest = nextLargest.rc;
if (largest != null) {
while (largest.rc != null) {
nextLargest = largest;
largest = largest.rc;
}
c.get().node = largest.node;
nextLargest.rc = largest.lc;
}
else {
nextLargest.rc = c.get().rc;
if (p.get().lc == c.get())
p.get().lc =nextLargest;
else
p.get().rc = nextLargest;
}
} // end case 3
return true;
}
} // end of delete
public boolean update(String id, Student_Pham newStudent) {
if(delete(id) == false)
return false;
else if (insert(newStudent) == false)
return false;
return true;
} // end update
public void showAll() {
if (root == null)
System.out.println("Structure is empty.");
else
LNRoutputTraversal(root);
} //end showAll
private void LNRoutputTraversal(TreeNode root) {
if (root.lc != null)
LNRoutputTraversal(root.lc);
System.out.println(root.node);
if (root.rc != null)
LNRoutputTraversal(root.rc);
}
public class TreeNode {
private Student_Pham node;
private TreeNode lc;
private TreeNode rc;
public TreeNode() {}
}
private boolean findNode(String targetKey, TreeNodeWrapper parent, TreeNodeWrapper child) {
parent.set(root);
child.set(root);
if (root == null)
return true;
while (child.get() != null) {
if(child.get().node.getId().compareTo(targetKey) == 0)
return true;
else {
parent.set(child.get());
if(targetKey.compareTo(child.get().node.getId()) < 0)
child.set(child.get().lc);
else
child.set(child.get().rc);
}
} //end while
return false;
}
public class TreeNodeWrapper {
TreeNode treeRef = null;
public TreeNodeWrapper() {}
public TreeNode get() {return treeRef;}
public void set(TreeNode t) {treeRef = t;}
}
}
I am currently trying to take a text file, and break the text file into words. I am then attempting to store each word as a node in a binary tree. After doing so I also try to print the binary tree. For some reason when i run my code i am now getting caught in an infinite loop but i don't understand where or why that is if you can see where i am getting caught that would be a great help thanks
public class Tester {
public static void main(String[] args) throws FileNotFoundException {
Tester run = new Tester();
run.it();
}
public void it() throws FileNotFoundException {
BTree theTree = new BTree();
String str = this.readInFile();
int position = 0;
String newWord = this.breakIntoWords(str, position);
while(newWord != null){
theTree.add(newWord);
newWord = this.breakIntoWords(str, position);
}
theTree.print();
}
public String readInFile() throws FileNotFoundException {
String myFile = "";
int numWords = 0;
Scanner myScan = new Scanner(new File("Dracula.txt"));
while(myScan.hasNext() == true) {
myFile += myScan.nextLine() + " ";
}
return myFile;
}
public String breakIntoWords(String myFile, int position) {
String nextWord = null;
char next = myFile.charAt(position);
next = Character.toLowerCase(next);
// First trim beginning
while (((next < 'a') || (next > 'z')) && !Character.isDigit(next)) {
position++;
next = myFile.charAt(position);
next = Character.toLowerCase(next);
}
// Now pull only letters or numbers until we hit a space
while(!Character.isWhitespace(next)) {
if (Character.isLetterOrDigit(next)) {
nextWord += myFile.charAt(position);
}
position++;
next = myFile.charAt(position);
}
return nextWord;
}
public class BTree {
private BTNode root;
private int nodeCount;
public boolean add(String word){
BTNode myNode = new BTNode(word);
if(root == null){
root = myNode;
nodeCount++;
return true;
}
if(findNode(word)){
int tmp = myNode.getNumInstance();
tmp++;
myNode.setNumInstance(tmp);
return false;
}
BTNode temp = root;
while(temp != null){
if(word.compareTo(temp.getMyWord()) < 0) {
if(temp.getRightChild() == null){
temp.setLeftChild(myNode);
nodeCount++;
return true;
} else {
temp = temp.getRightChild();
}
} else {
if(temp.getLeftChild() == null){
temp.setLeftChild(myNode);
nodeCount++;
return true;
} else {
temp = temp.getLeftChild();
}
}
}
return false;
}
public boolean findNode(String word) {
return mySearch(root, word);
}
private boolean mySearch(BTNode root, String word) {
if (root == null) {
return false;
}
if ((root.getMyWord().compareTo(word) < 0)) {
return true;
} else {
if (word.compareTo(root.getMyWord()) > 0) {
return mySearch(root.getLeftChild(), word);
} else {
return mySearch(root.getRightChild(), word);
}
}
}
public void print() {
printTree(root);
}
private void printTree(BTNode root) {
if (root == null) {
System.out.print(".");
return;
}
printTree(root.getLeftChild());
System.out.print(root.getMyWord());
printTree(root.getRightChild());
}
public int wordCount() {
return nodeCount;
}
You repeatedly call this.breakIntoWords(str, position) with the same str and position, using its return value to decide when to stop. Since nothing changes from the one iteration to the next, the loop never terminates.
I have fixed the issue with the infinite loops but it seems like now when I try to use the function find, it always returns a value null. Any ideas of what's happening? Also for some reason I'm getting a NullPointerException in my delete function. Please can you help me here guys?
package ui;
import java.time.LocalDate;
import bp.BinaryTree;
public class Main {
public static void main(String[] args) {
BinaryTree myTree = new BinaryTree();
myTree.insert(LocalDate.of(2014,12,01));
myTree.insert(LocalDate.of(2014,12,02));
myTree.insert(LocalDate.of(2014,12,03));
myTree.insert(LocalDate.of(2013,12,04));
myTree.insert(LocalDate.of(2012,12,04));
myTree.insert(LocalDate.of(2011,12,04));
myTree.insert(LocalDate.of(2010,12,04));
myTree.insert(LocalDate.of(2014,12,04));
myTree.insert(LocalDate.of(2014,12,05));
myTree.insert(LocalDate.of(2014,12,06));
myTree.insert(LocalDate.of(2014,12,07));
System.out.println(myTree);
System.out.println(myTree.getSize());
System.out.println(myTree.showMaximumValue());
System.out.println(myTree.showMinimumValue());
System.out.println(myTree.find(LocalDate.of(2014,12,07)));
}
public class BinaryTree implements IBinaryTree {
public Node root = null;
private int sizeOfTree = 0;
#Override
public LocalDate showMinimumValue() {
Node current;
Node last=null;
current = root;
while (current != null) {
last = current;
current = current.getLeftChild();
}
return last.getDate();
}
#Override
public LocalDate showMaximumValue() {
Node current;
Node last=null;
current = root;
while (current != null) {
last = current;
current = current.getRightChild();
}
return last.getDate();
}
#Override
public boolean isEmpty() {
if (root == null) {
return true;
} else
return false;
}
public int getDepth(Node n) {
int currentDepth = 0;
int depth = 0;
if (n != null) {
currentDepth++;
if (currentDepth > depth) {
depth = currentDepth;
}
getDepth(n.getLeftChild());
getDepth(n.getRightChild());
currentDepth--;
}
return depth;
}
#Override
public int getSize() {
return sizeOfTree;
}
#Override
public void clear() {
root = null;
}
#Override
public void insert(LocalDate valueToInsert) {
if (isEmpty()) {
root = new Node(valueToInsert);
sizeOfTree++;
} else {
Node n = root;
Node oldParent = null;
boolean lastDirectWasLeft = false;
sizeOfTree++;
while (n != null) {
oldParent = n;
if (valueToInsert.isBefore(n.getDate())) {
n = n.getLeftChild();
lastDirectWasLeft = true;
} else {
n = n.getRightChild();
lastDirectWasLeft = false;
}
}
if (lastDirectWasLeft) {
oldParent.setLeftChild(new Node(valueToInsert));
} else {
oldParent.setRightChild(new Node(valueToInsert));
}
}
}
#Override
public void delete(LocalDate valueToDelete) {
Node current = root;
Node parent = root;
boolean isLeftChild = true;
while (current.getDate() != valueToDelete) {
parent = current;
if (valueToDelete.isBefore(current.getDate())) {
isLeftChild = true;
current = current.getLeftChild();
} else {
isLeftChild= false;
current = current.getRightChild();
}
if (current == null) {
break;
}
}
//When there is no children, cut the string
if(current.getLeftChild().equals(null)
&& current.getRightChild().equals(null)) {
if (current == root) {
root = null;
} else if (isLeftChild) {
parent.setLeftChild(null);
} else {
parent.setRightChild(null);
}
}
//When there is no right child, replace with left child
else if (current.getRightChild().equals(null)) {
if (current == root) {
root = current.getLeftChild();
} else if (isLeftChild) {
parent.setLeftChild(current.getLeftChild());
} else
parent.setRightChild(current.getLeftChild());
}
//When there is no left child, replace with right child
else if (current.getLeftChild() == null) {
if (current == root) {
root = current.getRightChild();
} else if (isLeftChild) {
parent.setLeftChild(current.getRightChild());
} else
parent.setRightChild(current.getRightChild());
}
//has grandchildren, pass them to the grandpas
else {
//find the grandchildren
Node successor = getSuccessor(current);
if (current == root) {
root = successor;
} else if (isLeftChild) {
parent.setLeftChild(successor);
} else {
parent.setRightChild(successor);
}
//bring grandkids and granppas together
successor.setLeftChild(current.getLeftChild());
}
}
private Node getSuccessor (Node otroNode) {
Node successorParent = otroNode;
Node successor = otroNode;
Node current = otroNode.getRightChild();
while (current != null) {
successorParent = successor;
successor = current;
current = current.getLeftChild();
}
if (successor != otroNode.getRightChild()) {
successorParent.setLeftChild(successor.getRightChild());
successor.setRightChild(otroNode.getRightChild());
}
return successor;
}
#Override
public Node find(LocalDate valueToFind) {
Node current = root;
while (current.getDate() != valueToFind) {
if (valueToFind.isBefore(current.getDate())) {
current = current.getLeftChild();
} else {
current = current.getRightChild();
}
if (current == null) {
return null;
}
}
return current;
}
if (isEmpty()) {
return null;
}
if (root.getDate().isAfter(valueToFind)) {
find(root.getLeftChild().getDate());
} else if (root.getDate().isBefore(valueToFind)) {
find(root.getRightChild().getDate());
} else if (root.getDate().equals(valueToFind) ) {
return root;
}
return null;
**/
private String toString(Node todoElArbol) {
if (todoElArbol == null){
return "";
} else {
return (toString(todoElArbol.getLeftChild()) + ","
+ todoElArbol.getDate() + ","
+ toString(todoElArbol.getRightChild()))
.replaceAll(",+", ",").replaceAll("^,", "").replaceAll(",$", "");
}
}
#Override
public String toString() {
return toString(root);
}
}
The Node class:
import java.time.LocalDate;
public class Node implements IBinaryTreeNode {
private LocalDate date;
private Node leftChild;
private Node rightChild;
public Node (LocalDate valueToInsert) {
date = valueToInsert;
}
#Override
public LocalDate getDate() {
return date;
}
#Override
public void setDate(LocalDate pDate) {
date = pDate;
}
#Override
public Node getLeftChild() {
return leftChild;
}
#Override
public void setLeftChild(Node pLeftChild) {
leftChild = pLeftChild;
}
#Override
public Node getRightChild() {
return rightChild;
}
#Override
public void setRightChild(Node pRightChild) {
rightChild = pRightChild;
}
}
Your binary search is.... broken.
#Override
public Node find(LocalDate valueToFind) {
if (isEmpty()) {
return null;
}
if (root.getDate().isAfter(valueToFind)) {
find(root.getLeftChild().getDate());
} else if (root.getDate().isBefore(valueToFind)) {
find(root.getRightChild().getDate());
} else if (root.getDate() == valueToFind) {
return root;
}
return null;
}
That method is supposed to recursively find a value in the tree (a depth-first search).
Methods like that are normally implemented in two parts, the public part, and the implementation for the recursion:
#Override
public Node find(LocalDate valueToFind) {
if (isEmpty()) {
return null;
}
return findRecursive(root, valueToFind);
}
then the private/recursive method:
private Node findRecursive(Node node, LocalDate valueToFind) {
if (node == null) {
return null;
}
if (node.getDate().isAfter(valueToFind)) {
return findRecursive(node.getLeftChild(), valueToFind);
}
if (node.getDate().isBefore(valueToFind)) {
return findRecursive(root.getRightChild(), valueToFind);
}
if (node.getDate().equals(valueToFind)) {
return node;
}
return null;
}
Note, no references to root in the recursive call, and also changed the == comparison to .equals(...).
I suggest the class Node should implement the Comparable interface, then you can get rid of the help method isBefore and isAfter, which will make your code much more readable.
first time asking around here. I'm doing an AVLTree generic and there is a method in the Node that gives me an Iterator that returns me a Object array. The thing is that when I try to get that array with the objects of one of my none generic classes it sends me this.
Exception in thread "main" java.lang.ClassCastException: [LestructuraDeDatos.NodoAVL; cannt be cast to [Lmundo.Categoria;
Here is the node class
public class NodoAVL <T extends Comparable <T>>
{
//--------------------------------------------------------------------------------------------
//Atributos
//--------------------------------------------------------------------------------------------
private NodoAVL<T> izquierdo;
private NodoAVL<T> derecho;
private T elemento;
private String criterio;
//--------------------------------------------------------------------------------------------
//Constructor
//--------------------------------------------------------------------------------------------
public NodoAVL(T elem, String crit)
{
elemento = elem;
izquierdo = null;
derecho = null;
criterio = crit;
}
//--------------------------------------------------------------------------------------------
//Metodos
//--------------------------------------------------------------------------------------------
public NodoAVL<T> getIzquierdo() {
return izquierdo;
}
public void setIzquierdo(NodoAVL<T> izquierdo) {
this.izquierdo = izquierdo;
}
public NodoAVL<T> getDerecho() {
return derecho;
}
public void setDerecho(NodoAVL<T> derecho) {
this.derecho = derecho;
}
public String getCriterio() {
return criterio;
}
public void setCriterio(String criterio) {
this.criterio = criterio;
}
public boolean soyHoja()
{
if(izquierdo == null && derecho == null)
{
return true;
}
return false;
}
public T getElemento() {
return elemento;
}
public void setElemento(T elemento) {
this.elemento = elemento;
}
public void agregarElemento(T elemento, String Crit)
{
//Buscarlo antes de agregar, no puede haber iguales en el arbol
if(buscarElemento(Crit)==null)
if(soyHoja())
{
if(elemento.compareTo(this.elemento)>0)
{
NodoAVL<T> nuevo = new NodoAVL<T>(elemento, Crit);
setDerecho(nuevo);
}else if(elemento.compareTo(this.elemento)<0)
{
NodoAVL<T> nuevo = new NodoAVL<T>(elemento, Crit);
setIzquierdo(nuevo);
}
}else
{
NodoAVL<T> nuevo = new NodoAVL<T>(elemento,Crit);
if(this.elemento.compareTo(elemento)>0 && izquierdo == null)
{
izquierdo = nuevo;
}
else if(this.elemento.compareTo(elemento)>0)
{
izquierdo.agregarElemento(elemento,Crit);
}
else if(this.elemento.compareTo(elemento)<0 && derecho == null)
{
derecho = nuevo;
}
else if( this.elemento.compareTo(elemento)<0)
{
derecho.agregarElemento(elemento, Crit);
}
}
balanciarSubArbol();
}
public NodoAVL<T> rotarIzq(NodoAVL<T> rotar)
{
NodoAVL<T> temp = rotar.derecho;
rotar.setDerecho(temp.izquierdo);
temp.setIzquierdo(rotar);
return temp;
}
public NodoAVL<T> rotarDer(NodoAVL<T> rotar)
{
NodoAVL<T> temp = rotar.izquierdo;
rotar.setIzquierdo(temp.derecho);
temp.setDerecho(rotar);
return temp;
}
public int darBalance()
{
if(soyHoja())
{
return 0;
}
else
{
int izq = (izquierdo == null)?0:izquierdo.darAltura();
int der = (derecho == null)? 0 :derecho.darAltura();
return (izq - der);
}
}
public NodoAVL<T> dobleRotacionDerIzq(NodoAVL<T> nodo)
{
nodo.setDerecho(rotarDer(nodo.getDerecho()));
return rotarIzq(nodo);
}
public NodoAVL<T> dobleRotacionIzqDer(NodoAVL<T> nodo)
{
nodo.setIzquierdo(rotarIzq(nodo.getIzquierdo()));
return rotarDer(nodo);
}
public void balanciarSubArbol()
{
int valor = darBalance();
if(-2==valor || valor==2)
{
if(valor<0 && derecho.darBalance()<0)
{
if(derecho.darBalance()<-2)
{
derecho.balanciarSubArbol();
}else
{
rotarIzq(this);
}
}else if(valor<0 && derecho.darBalance()>0)
{
if(derecho.darBalance()>2)
{
derecho.balanciarSubArbol();
}else
{
dobleRotacionDerIzq(this);
}
}else if(valor>0 && izquierdo.darBalance()>0)
{
if(izquierdo.darBalance()>2)
{
izquierdo.balanciarSubArbol();
}else
{
rotarDer(this);
}
}else if(valor>0 && izquierdo.darBalance()<0)
{
if(izquierdo.darBalance()<-2)
{
izquierdo.balanciarSubArbol();
}else
{
dobleRotacionIzqDer(this);
}
}
}
}
public NodoAVL<T> eliminarElemento(T elemento)
{
if(soyHoja() && this.elemento==elemento)
{
return null;
}else if(soyHoja() && this.elemento!=elemento)
{
return this;
}
else
{
if(this.elemento.compareTo(elemento)==0)
{
if(izquierdo != null && derecho != null)
{
NodoAVL<T> temp = derecho;
izquierdo.setDerecho(temp.getIzquierdo());
temp.setIzquierdo(izquierdo);
return temp;
}
else if(izquierdo != null)
{
return izquierdo;
}
else
{
return derecho;
}
}
else if(this.elemento.compareTo(elemento)>0)
{
izquierdo = izquierdo.eliminarElemento(elemento);
return this;
}
else if(this.elemento.compareTo(elemento)<0)
{
derecho = derecho.eliminarElemento(elemento);
return this;
}
balanciarSubArbol();
return this;
}
}
public T buscarElemento(String criterio)
{
if(this.criterio.equalsIgnoreCase(criterio))
{
return this.elemento;
}
else
{
T izq = (izquierdo != null)?izquierdo.buscarElemento(criterio):null;
T der = (derecho != null) ? derecho.buscarElemento(criterio):null;
if(izq != null)
{
return izq;
}else if(der != null)
{
return der;
}
}
return null;
}
public IteradorAVL<T> darElementos()
{
IteradorAVL<T> ite = new IteradorAVL<T> (this);
return ite;
}
public int darPeso()
{
if(soyHoja())
{
return 1;
}else
{
int izq = (izquierdo == null)? 0: izquierdo.darPeso();
int der = (derecho == null) ? 0:derecho.darPeso();
return (izq+der+1);
}
}
public int darAltura()
{
if(soyHoja())
{
return 1;
}
else
{
int izq = ( izquierdo == null ) ? 0 : izquierdo.darAltura( );
int der = ( derecho == null ) ? 0 : derecho.darAltura( );
return(izq>der || izq == der)?izq+1:der+1;
}
}
}
and the iterator class
public class IteradorAVL<T extends Comparable <T>> implements Iterator<T>{
//--------------------------------------------------------------------------------------------
//Atributos
//--------------------------------------------------------------------------------------------
private NodoAVL<T> arbolitoAVL;
private Object [] elementos;
private int posActual;
private int total;
private Stack<NodoAVL> nodePath = new Stack<NodoAVL>();
//--------------------------------------------------------------------------------------------
//Constructor
//--------------------------------------------------------------------------------------------
public IteradorAVL ( NodoAVL <T> nodo)
{
arbolitoAVL = nodo;
posActual = 0;
total = nodo.darPeso();
elementos = new NodoAVL[total];
}
//--------------------------------------------------------------------------------------------
//Metodos
//--------------------------------------------------------------------------------------------
#Override
public boolean hasNext()
{
return(total>posActual)?true:false;
}
#Override
public T next() {
T siguienteT =null;
NodoAVL<T> respuesta = arbolitoAVL;
//Guardo el nodo actual en la lista
//Avancce
while (arbolitoAVL != null) {
nodePath.push(arbolitoAVL);
elementos[posActual] = arbolitoAVL;
arbolitoAVL = arbolitoAVL.getIzquierdo();
posActual++;
}
if (!nodePath.isEmpty()) {
arbolitoAVL = nodePath.pop();
posActual++;
elementos[posActual] = arbolitoAVL;
siguienteT = arbolitoAVL.getElemento();
arbolitoAVL = arbolitoAVL.getDerecho();
}
return siguienteT;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
public Object[] darArreglo()
{
return elementos;
}
The reason ClassCastException occurs is only one that your trying to typecast an object of one class to an object of another class which are not compatible.
Example :
Object i = Integer.valueOf(42);
String s = (String)i; // ClassCastException thrown here.