I am currently having a difficulty understanding the role of a constructor when it comes to a Priority Queue. I have gone through and created methods such as peek, pop, length and etc for the queue however I am stuck to when it comes to the constructor. It is probably a mental block more than anything.
My class is as follows:
public class PQueue<T> {
private PQueueItem<T> head;
public static enum ORDER {
ASC, DESC;
}
public static ORDER DEFAULT_ORDER;
private ORDER order;
/**
* The default constructor for a PQueue, with the default order for priorities
*/
public PQueue() {
// ...add code
}
/**
* The constructor to make a new PQueue with a given order
*
* #param order
*/
public PQueue(ORDER order) {
// ...add code
}
/**
* Remove and return data from the item at the front of the queue
*
* #return
*/
public T pop() {
if(head == null) {
return null;
}
// temp variable to hold head data
T e1 = head.getData();
// gives the next item the head
head = head.getNext();
// returns temp variable
return e1;
}
/**
* Return the data from the item at the front of the queue, without removing the
* item itself
*
* #return
*/
public T peek() {
// returns head data
if(head == null) {
return null;
}
return head.getData();
}
/**
* Remove and return the item at the front of the queue
*
* #return
*/
public PQueueItem<T> popItem() {
if (head == null) {
return null;
}
// temp variable to hold item
PQueueItem<T> e1 = this.head;
// gives the next item the head
this.head = head.getNext();
// returns temp variable
return e1;
}
/**
* Return the item at the front of the queue without removing it
*
* #return
*/
public PQueueItem<T> peekItem() {
if (head == null) {
return null;
}
return head;
}
/**
* Insert a new item into the queue, which should be put in the right place
* according to its priority. That is, is order == ASC, then the new item should
* appear in the queue before all items with a HIGHER priority. If order ==
* DESC, then the new item should appear in the queue before all items with a
* LOWER priority.
*
* #param data
* #param priority
*/
public void insert(T data, int priority) {
if (order == ORDER.ASC) {
// current item
PQueueItem<T> e1 = head;
while (e1.getNext() != null) {
// is inserted item greater than current item
if (priority > e1.getPriority()) {
// is inserted item smaller than next item
if (priority < e1.getNext().getPriority()) {
// create and insert new item, reassign links in the list
PQueueItem<T> newPQ = new PQueueItem<T>(data, priority);
newPQ.setNext(e1.getNext());
e1.setNext(newPQ);
}
// check to see if priority equates to the next item's priority
else if (priority == e1.getNext().getPriority()) {
// is new item's data alphabetically greater than the next item's data
if (((String) data).compareToIgnoreCase((String) e1.getNext().getData()) > 0) {
PQueueItem<T> nextPQ = e1.getNext();
PQueueItem<T> newPQ = new PQueueItem<T>(data, priority);
newPQ.setNext(nextPQ.getNext());
nextPQ.setNext(newPQ);
} else {
PQueueItem<T> newPQ = new PQueueItem<T>(data, priority);
newPQ.setNext(e1.getNext());
e1.setNext(newPQ);
}
} else {
// iterate current item
e1 = head.getNext();
}
}
// if item to be inserted is smaller than the current item
else if (priority < e1.getPriority()) {
PQueueItem<T> newPQ = new PQueueItem<T>(e1.getData(), e1.getPriority());
newPQ.setNext(e1.getNext());
e1.setData(data);
e1.setPriority(priority);
}
}
} else if (order == ORDER.DESC) {
PQueueItem<T> e1 = head;
while (e1.getNext() != null) {
// is inserted item less than current item
if (priority < e1.getPriority()) {
// is inserted item greater than next item
if (priority > e1.getNext().getPriority()) {
// create and insert new item, reassign links in the list
PQueueItem<T> newPQ = new PQueueItem<T>(data, priority);
newPQ.setNext(e1.getNext());
e1.setNext(newPQ);
}
// check to see if priority equates to the next item's priority
else if (priority == e1.getNext().getPriority()) {
// is new item's data alphabetically less than the next item's data
if (((String) data).compareToIgnoreCase((String) e1.getNext().getData()) < 0) {
PQueueItem<T> nextPQ = e1.getNext();
PQueueItem<T> newPQ = new PQueueItem<T>(data, priority);
newPQ.setNext(nextPQ.getNext());
nextPQ.setNext(newPQ);
} else {
PQueueItem<T> newPQ = new PQueueItem<T>(data, priority);
newPQ.setNext(e1.getNext());
e1.setNext(newPQ);
}
} else {
// iterate current item
e1 = head.getNext();
}
}
// if item to be inserted is greater than the current item
else if (priority > e1.getPriority()) {
PQueueItem<T> newPQ = new PQueueItem<T>(e1.getData(), e1.getPriority());
newPQ.setNext(e1.getNext());
e1.setData(data);
e1.setPriority(priority);
}
}
}
}
/**
* Return the length of the queue
*
* #return
*/
public int length() {
if (head == null) {
return 0;
} else {
int size = 0;
for (PQueueItem<T> i = head; i.getNext() != null; i = i.getNext()) {
size++;
}
return size;
}
}
public String toString() {
int i = length();
PQueueItem<T> current = head;
StringBuffer sb = new StringBuffer();
while (i > 0) {
sb.append(current.toString());
if (i > 1)
sb.append(": ");
current = current.getNext();
i--;
}
return sb.toString();
}
}
Also when it comes to the code I have done a few null checks however I have read that there is a method of using optional which is far cleaner and better. If you have any recommendations can you please let me know?
The other class for the PQueueItem is as below:
public class PQueueItem<T> {
private int priority;
private T data;
private PQueueItem<T> next;
public PQueueItem(T data, int priority) {
this.data = data;
this.priority = priority;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public PQueueItem<T> getNext() {
return next;
}
public void setNext(PQueueItem<T> next) {
this.next = next;
}
public String toString() {
return String.format("[%s,%d]", data.toString(), priority);
}
}
Thank you in advanced and any criticism will be taken with gratitude.
Related
My data structures project on dequeues is passing all junit tests except for one. the "removeFrontRemoveRear" test. It keeps returning null instead of the
student name.
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Dequeue <E> {
private int front;
private int rear;
private E[] elements;
private static final int DEFAULT_CAPACITY = 5;
/**
* Constructor sets up an empty double-ended
* queue
*/
#SuppressWarnings("unchecked")
public Dequeue() {
elements = (E[]) new Object[DEFAULT_CAPACITY];
front = 0;
rear = elements.length - 1;
}
/**
* Inserts item at the front of the dequeue. Throws
* an exception if the item could not be inserted
* #param anEntry the item to be added (Student)
* #return true
*/
public boolean addFront(E anEntry) {
if (empty()) {
front = rear = 0;
elements[front] = anEntry;
}
else if (isFull()) {
reallocate();
front = (front + (elements.length - 1)) % elements.length;
}
else {
front = (front + (elements.length - 1)) % elements.length;
}
elements[front] = anEntry;
return true;
}
/**
* private method to check if the dequeue is full
* #return true only if dequeue is full (has
* 1 empty spot)
*/
private boolean isFull() {
if (size() == elements.length -1) {
return true;
}
return false;
}
/**
*Doubles and adds 1 to the size of the dequeue
*then reallocates the data.
*/
#SuppressWarnings("unchecked")
private void reallocate() {
E[] newData = (E[]) new Object[size() * 2 + 1];
int indexOfFront = front;
for(int i = 0; i < size(); i++) {
newData[i] = elements[indexOfFront];
indexOfFront = (indexOfFront + 1) % elements.length;
}
rear = size() - 1;
front = 0;
elements = newData;
}
/**
* Inserts item at the rear of the dequeue.
* Throws an exception if the item could not be inserted
* #param anEntry the entry being inserted into the end of the queue
* #return true
*/
public boolean addRear(E anEntry) {
if (empty()) {
front = rear = 0;
elements[rear] = anEntry;
}
else if (isFull()) {
reallocate();
rear = (rear + 1) % elements.length;
}
else {
rear = (rear + 1) % elements.length;
}
elements[rear] = anEntry;
return true;
}
/**
* This method checks if the dequeue is empty
* #return true if the dequeue is empty. otherwise
* returns false
*/
public boolean empty() {
if (front == 0 && rear == elements.length-1) {
return true;
}
return false;
}
/**
* #return the dequeue's iterator
*/
public Iterator<E> iterator() {
return new dequeueIterator();
}
/**
* implementation of Iterator interface
* with inner class
*/
private class dequeueIterator implements Iterator<E> {
private int index;
private int count = 0;
/**
* references the front dequeue element
* and initializes the dequeueIterator object
*/
public dequeueIterator(){
index = front;
}
/**
*#return true it there are additional
* elements in the dequeue
*/
#Override
public boolean hasNext() {
return count < size();
}
/**
* #return the next element in the queue
*/
#Override
public E next() {
if(!hasNext()) {
throw new NoSuchElementException();
}
E returnValue = elements[index];
index = (index + 1) % elements.length;
count++;
return returnValue;
}
/**
* removes the elements accessed by the
* iterator object
*/
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
/**
* //Returns the entry at the front of the
* dequeue without removing it; returns
* NoSuchElementException if the dequeue
* is empty
* #return the object at the front of dequeue
*/
public E peekFront() {
if (empty())
throw new NoSuchElementException();
else
return elements[front];
}
/**
* returns the item at the rear of the dequeue, throws
* NoSuchElementException if empty.
* #return the element in the rear
*/
public E peekRear() {
if (empty())
throw new NoSuchElementException();
else
return elements[rear];
}
/**
*Removes the entry at the front of the dequeue and
*returns it if the dequeue is not empty. If the
*dequeue is empty, throws a NoSuchElementException
* #return front element before removing it
*/
public E removeFront() {
if (empty())
throw new NoSuchElementException();
E temp = elements[front];
elements[front] = null;
front = (front++) % elements.length;
return temp;
}
/**
* Removes the entry at the rear of the dequeue and
*returns it if the dequeue is not empty. If the
*dequeue is empty, throws a NoSuchElementException
* #return rear element before removing it
*/
public E removeRear() {
if (empty())
throw new NoSuchElementException();
E temp = elements[rear];
elements[rear] = null;
rear = (rear + elements.length - 1) % elements.length;
return temp;
}
/**
* Gets the amount of elements in the dequeue
* #return the number of elements in the dequeue
*/
public int size() {
int count = 0;
int indexOfFront = front;
int nextRearPosition = (rear + 1) % elements.length;
while(indexOfFront != nextRearPosition) {
count++;
indexOfFront = (indexOfFront + 1) % elements.length;
}
return count;
}
}
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.NoSuchElementException;
public class DequeueTest {
Dequeue<Student> q;
Student s1, s2, s3, s4, s5, s6, s7, s8;
#BeforeEach
public void setUp() throws Exception {
q = new Dequeue<Student> ();
s1 = new Student("John", "Doe");
s2 = new Student ("Jane", "Smith");
s3 = new Student ("Bob", "Taylor");
s4 = new Student ("Anne", "Frank");
s5 = new Student("Frank", "Gauvin");
s6 = new Student("Kevin", "Austin");
s7 = new Student ("Cindy", "Bryant");
s8 = new Student ("Peter", "Lander");
}
#Test
public void testaddFrontAddRear() {
q.addFront(s1);
q.addFront(s2);
q.addFront(s3);
assertThat(q.peekFront(), is(s3)); // assertEquals(s3, q.peekFront());
q.addRear(s4);
q.addRear(s5);
q.addFront(s6);
q.addRear(s7);
assertThat(q.peekRear(), is(s7)); // assertEquals(s7, q.peekRear());
assertThat(q.size(), is(7)); // assertEquals(7, q.size());
}
#Test
public void testRemoveFrontRemoveRear() {
q.addFront(s1);
q.addFront(s2);
q.addFront(s3);
q.addRear(s4);
q.addRear(s5);
q.addFront(s6);
q.addRear(s7);
assertThat(q.removeFront(), is(s6)); // assertEquals(s6, q.removeFront());
assertThat(q.removeRear(), is(s7)); // assertEquals(s7, q.removeRear());
assertThat(q.removeFront(), is(s3)); // assertEquals(s3, q.removeFront() );
assertThat(q.size(), is(4)); // assertEquals(4, q.size());
assertThat(q.removeRear(), is(s5)); // assertEquals(s5, q.removeRear());
assertThat(q.removeFront(), is(s2)); // assertEquals(s2, q.removeFront());
assertThat(q.size(), is(2)); // assertEquals(2, q.size());
assertThat(q.removeFront(), is(s1)); // assertEquals(s1, q.removeFront());
assertThat(q.removeRear(), is(s4)); // assertEquals(s4, q.removeRear());
assertTrue(q.empty());
assertTrue(q.size() == 0);
}
#Test
public void testIterator() {
q.addFront(s1);
q.addFront(s2);
q.addFront(s3);
q.addRear(s4);
assertEquals(4, q.size() );
q.addRear(s5);
q.addFront(s6);
q.addRear(s7);
assertEquals(7, q.size() );
Iterator <Student> iter = q.iterator();
ArrayList<Student> list = new ArrayList<Student>();
while (iter.hasNext()) {
list.add(iter.next() );
}
assertThat(list.get(0), is(s6)); // assertEquals(s6, list.get(0));
assertThat(list.get(1), is(s3)); // assertEquals(s3, list.get(1));
assertThat(list.get(2), is(s2)); // assertEquals(s2, list.get(2));
assertThat(list.get(3), is(s1)); // assertEquals(s1, list.get(3));
assertThat(list.get(4), is(s4)); // assertEquals(s4, list.get(4));
assertThat(list.get(5), is(s5)); // assertEquals(s5, list.get(5));
assertThat(list.get(6), is(s7)); // assertEquals(s7, list.get(6));
}
#Test
public void testPeekFrontOnEmptyQueue() throws NoSuchElementException {
assertThrows(NoSuchElementException.class, () ->
{Dequeue<Student> q = new Dequeue<Student>();
q.peekFront();});
}
#Test
public void testRearFrontOnEmptyQueue() throws NoSuchElementException{
assertThrows(NoSuchElementException.class, () ->
{Dequeue<Student> q = new Dequeue<Student>();
q.peekRear();});
}
#Test
public void testRemoveFrontOnEmptyQueue() throws NoSuchElementException {
assertThrows(NoSuchElementException.class, () ->
{Dequeue<Student> q = new Dequeue<Student>();
q.removeFront();});
}
#Test
public void testRemoveRearOnEmptyQueue() throws NoSuchElementException
{
assertThrows(NoSuchElementException.class, () ->
{Dequeue<Student> q = new Dequeue<Student>();
q.removeRear();});
}
}
/** Abstraction of a Student entity */
public class Student implements Comparable <Student> {
private String firstName;
private String lastName;
/** Initialize a Student
#param first firstName
#param last lastName
*/
public Student(String first, String last) {
firstName = first;
lastName = last;
}
/** Mutator Method
#param aName firstName
*/
public void setFirstName(String aName) {
firstName = aName;
}
/** Accessor Method
#return firstName of this Student
*/
public String getFirstName() {
return firstName;
}
/** Mutator Method
#param aName lastName
*/
public void setLastName(String aName) {
lastName = aName;
}
/** Accessor Method
#return lastName of this Student
*/
public String getLastName() {
return lastName;
}
#Override
public String toString() {
String str = "";
str += (lastName + "," + firstName);
return str;
}
/* this version overloads the equals method (note the
signature of this method).
*/
public boolean equals(Student s) {
return ( (this.lastName.equalsIgnoreCase(s.lastName)) &&
(this.firstName.equalsIgnoreCase(s.firstName)));
}
/* We need to override this method so indexOf and
contains methods work. Both of them use this version
equals method
*/
#Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj == this) return true;
if (!(obj instanceof Student)) return false;
else {
Student s = (Student) obj;
return ( this.equals(s)); // calls the
equals(Student) method
}
}
/**
#return
a negative integer if "s1 < s2"; 0 if "s1 == s2"
a positive integer if "s1 > s2"
*/
#Override
public int compareTo(Student s) {
int result = lastName.compareToIgnoreCase(s.lastName);
if (result != 0) return result;
else
return (firstName.compareToIgnoreCase(s.firstName));
}
}
The expected result is but the actual result was null.
I am not sure what to try. I am drawing a blank. The error is brought forth in line 55 of dequeueTest.
I'm trying to implement iterator on AVL tree, I'm stuck at this specific function:
/**
* #return an iterator for the Avl Tree. The returned iterator iterates over the tree nodes.
* in an ascending order, and does NOT implement the remove() method.
*/
public Iterator<Integer> iterator(){
List myList=new ArrayList<>();
Node counter=root;
Node counter1=root.getChildernLeft();
if(counter1==null){
myList.add(counter1);
}
Node counter1=root.getChildernLeft();
}
I added my two classes:
full code, Node class:
public class Node {
private Node parent;
private Node childernRight;
private Node childernLeft;
private int data;
private int height;
/**
* constractor
*/
public Node(int data, Node childernLeft, Node childernRight) {
this.data = data;
this.childernLeft = childernLeft;
this.childernRight = childernRight;
this.childernRight.setParent(this);
this.childernLeft.setParent(this);
}
public Node(int data) {
this.data = data;
}
public Node getParent() {
return parent;
}
public Node getChildernRight() {
return childernRight;
}
public Node getChildernLeft() {
return childernLeft;
}
public void setParent(Node parent) {
this.parent = parent;
}
public void setChildernRight(Node childernRight) {
this.childernRight = childernRight;
this.childernRight.setParent(this);
}
public void setChildernLeft(Node childernLeft) {
this.childernLeft = childernLeft;
this.childernLeft.setParent(this);
}
public int getData() {
return data;
}
public String toString() {
if (this.childernLeft != null && this.getChildernRight() != null) {
return childernLeft.toString() + "," + this.data + "," + childernRight.toString();
} else if (this.childernLeft != null && this.getChildernRight() == null) {
return childernLeft.toString() + "," + this.data;
} else if (this.childernLeft == null && this.getChildernRight() != null) {
return this.data + "," + childernRight.toString();
} else {
return this.data + "";
}
}
public int balanceFactor() {
int balanceFactor = childernRight.height - childernLeft.height;
return balanceFactor;
}
public boolean hasChildrenRight() {
if (this.childernRight != null) {
return true;
}
else{
return false;
}
}
public boolean hasChildrenLeft() {
if (this.childernLeft != null) {
return true;
}
else{
return false;
}
}
/**
* if we have many children in the tree
*/
public void addNode(Node val){
if(hasChildrenRight()&&this.data>val.data){
this.setChildernRight(val);
}
if(!hasChildrenLeft()&&this.data<val.data){
this.setChildernLeft(val);
}
if(!hasChildrenLeft()&&!hasChildrenRight()){
if(this.data>val.data){
setChildernLeft(val);
}
else{
setChildernRight(val);
}
}
if(val.data>this.data){
childernRight.addNode(val);
}
else{
childernLeft.addNode(val);
}
}
}
full code for AvlTree:`
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class AvlTree {
private Node root;
private int size;
/**
* default constructor.
*/
public AvlTree() {
this.root = null;
this.size = 0;
}
/**
* A constructor that builds a new AVL tree containing all unique values in the input
* array
*
* #param data the values to add to tree
*/
public AvlTree(int[] data) {
for (int i = 0; i < data.length; i++) {
add(data[i]);
}
}
/**
* A copy constructor that creates a deep copy of the given oop.ex4.data_structures.AvlTree. The new tree
* contains all the values of the given tree, but not necessarily in the same structure.
*
* #param avlTree an AVL tree.
*/
public AvlTree(AvlTree avlTree) {
}
/**
* Add a new node with the given key to the tree.
*
* #param newValue the value of the new node to add.
* #return true if the value to add is not already in the tree and it was successfully added,
* false otherwise.
*/
public boolean add(int newValue) {
if (root == null) {
root = new Node(newValue);
size++;
return true;
}
Node current = root;
Node parent = null;
while (current != null) {
if (current.getData() == newValue) {
return false;
}
parent = current;
if (newValue < current.getData()) {
current = current.getChildernLeft();
} else {
current = current.getChildernRight();
}
}
size++;
// when we here the new NODE Need to be chiled of Node hashmor in parent.
// addHelper is adding the new Node.2
// addHelper(newNodeToAdd, current);
return true;
}
private void addHelper(Node newNodeToAdd, Node current) {
// if (newNodeToAdd.getData() > current.getData()) {
// if (current.getChildernRight() == null) {
// current.setChildernRight(newNodeToAdd);
// } else {
// addHelper(newNodeToAdd, current.getChildernRight());
// }
// } else {
// if (current.getChildernLeft() == null) {
// current.setChildernLeft(newNodeToAdd);
// } else {
// addHelper(newNodeToAdd, current.getChildernLeft());
// }
// }
}
/**
* Check whether the tree contains the given input value.
*
* #param searchVal the value to search for.
* #return the depth of the node (0 for the root) with the given value if it was found in the tree, −1 otherwise.
*/
public int contains(int searchVal) {
Node current = root;
int depth = 0;
while (current != null) {
if (current.getData() == searchVal) {
return depth;
}
depth++;
if (searchVal < current.getData()) {
current = current.getChildernLeft();
} else {
current = current.getChildernRight();
}
}
return -1;
}
/**
* Removes the node with the given value from the tree, if it exists.
*
* #param toDelete the value to remove from the tree.
* #return true if the given value was found and deleted, false otherwise.
*/
public boolean delete(int toDelete) {
size -= 1;
return true;
}
/**
* #return the number of nodes in the tree.
*/
public int size() {
return size;
}
/**
* #return an iterator for the Avl Tree. The returned iterator iterates over the tree nodes.
* in an ascending order, and does NOT implement the remove() method.
*/
public Iterator<Integer> iterator(){
List myList=new ArrayList<>();
Node counter=root;
Node counter1=root.getChildernLeft();
if(counter1==null){
myList.add(counter1);
}
Node counter1=root.getChildernLeft();
}
/**
* Calculates the minimum number of nodes in an AVL tree of height h
*
* #param h the height of the tree (a non−negative number) in question.
* #return the minimum number of nodes in an AVL tree of the given height.
*/
public static int findMinNodes(int h) {
// I SOVLE THIS WITH ROCKISA
int counterMin = 0;
if (h == 0) {
return counterMin = 1;
}
if (h == 1) {
return counterMin = 2;
}
return (findMinNodes(h - 1) + findMinNodes(h - 2) + 1);
}
/**
* Calculates the maximum number of nodes in an AVL tree of height h.
*
* #param h the height of the tree (a non−negative number) in question.
* #return the maximum number of nodes in an AVL tree of the given height.
*/
public static int findMaxNodes(int h) {
int counterMax = 0;
for (int i = 0; i < h; i++) {
counterMax += Math.pow(h, i);
}
return counterMax;
}
/**
* #return
*/
public String toString() {
if (root == null) {
return "";
}
return root.toString();
}
//THIS IS OK
public void RotationRr(Node valRotation) {
if (valRotation == root) {
Node keepRootChild = root.getChildernRight();
root.setChildernRight(null);
}
Node parent1 = valRotation.getParent();
Node keepRightChild = valRotation.getChildernRight();///4
valRotation.setChildernRight(null);
keepRightChild.setParent(parent1);
if (!keepRightChild.hasChildrenLeft()) {
keepRightChild.setChildernLeft(valRotation);
valRotation.setParent(keepRightChild);
} else {
keepRightChild.getChildernLeft().addNode(valRotation);
}
}
public void RotationLr(Node valRotation) {
RotationLl(valRotation);
}
/**
* ........CHECK.....!!!!TODO
*
* #param valRotation
*/
public void RotationLl(Node valRotation) {
Node parent2 = valRotation.getParent();
Node keepLeftChild = valRotation.getChildernLeft();
valRotation.setChildernLeft(null);
keepLeftChild.setParent(parent2);
if (!keepLeftChild.hasChildrenRight()) {
keepLeftChild.setParent(keepLeftChild);
} else {
keepLeftChild.getChildernRight().addNode(valRotation);
}
}
public void RotationRl(Node valRotation) {
RotationRr(valRotation);
}
public static void main(String[] args) {
AvlTree avlTree = new AvlTree();
avlTree.add(7);
avlTree.add(2);
System.out.println(avlTree.contains(2));
// System.out.println(avlTree.contains(5));
avlTree = new AvlTree();
avlTree.add(2);
avlTree.add(7);
System.out.println(avlTree.contains(2));
// System.out.println(avlTree);
}
}
`
You can implement a iterator using stack
public Iterator<V> iterator() {
return new Itr();
}
private class Itr<V> implements Iterator<V> {
TreeNode<V> localNode = (TreeNode<V>) root;
Stack<TreeNode<V>> stack;
public Itr() {
stack = new ArrayStack<TreeNode<V>>();
while (localNode != null) {
stack.push(localNode);
localNode = localNode.getLeftChield();
}
}
public boolean hasNext() {
return !stack.empty();
}
public V next() {
TreeNode<V> node = stack.pop();
V v = node.getValue();
if (node.getRightChield() != null) {
node = node.getRightChield();
while (node != null) {
stack.push(node);
node = node.getLeftChield();
}
}
return v;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
package phonelist;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class LinkedList {
private Node head;
private int size = 0;
public LinkedList() {
load(); // Load a contacts from a file
}
public void add(Contact contact) {
Node newNode = new Node(contact, null);
size++;
if (head == null) {
newNode.setNextNode(head);
head = newNode;
} else {
Node c = head;
while ((c.getNextNode() != null)) {
c = c.getNextNode();
}
newNode.setNextNode(c.getNextNode());
c.setNextNode(newNode);
}
}
public boolean remove(String name) {
return true;
}
public Contact search(String name) {
return null;
}
public String getAll() {
return null;
}
/** Save contacts to a text file **/
public void save() {
if (size == 0) {
return;
}
Scanner in = new Scanner(System. in );
try {
PrintWriter outFile = new PrintWriter("contacts.txt");
if (head != null) {
Node currentNode = head;
do {
Contact contact = currentNode.getContact();
outFile.println(contact.getName() + "," + contact.getNumber());
currentNode = currentNode.getNextNode();
} while (currentNode != null);
}
outFile.close();
} catch (FileNotFoundException e) {
System.out.println("Cannot find that file");
}
}
/** Load contacts from a text file **/
public void load() {
try {
FileReader file = new FileReader("contacts.txt");
Scanner inFile = new Scanner(file);
while (inFile.hasNext()) {
String contact = inFile.nextLine();
int index = contact.indexOf(',');
String name = contact.substring(0, index);
String number = contact.substring(index + 1, contact.length());
add(new Contact(name, number));
}
inFile.close();
} catch (FileNotFoundException e) {
System.out.println("Cannot find that file");
}
}
}
I cannot figure out how to remove a specific node, nor how to search properly. It keeps giving me a node location not what i have added. I have spent the last 5 hours working on this and I am unable to finish the rest without at least being able to search. If someone could give me a few pointers on here to begin or give me examples, it would be much appreciated.
Here is a way I have tried the remove method.
public boolean remove(String name) {
if (name.equals(name)) {
remove(name);
return true;
} else {
return false;}}
Node Class
package phonelist;
public class Node {
private Contact contact;
private Node next;
public Node(Contact contact, Node next) {
// Do something here
this.contact = contact;
this.next = next;
}
public void setNextNode(Node next) {
// Do something here
this.next = next;
}
public Node getNextNode() {
// Replace return null with something useful
return next;
}
public Contact getContact() {
// Replace return null with something useful
return contact;
}
}
Contact Class
package phonelist;
public class Contact {
private String name;
private String number;
public Contact(String name, String number) {
this.name = name;
this.number = number;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
}
In the LinkeList class Ive created a toString() method but i am currently only printing out a node location in memory not the actual data. Ideas?
#Override
public String toString() {
return "LinkedList{" + "head=" + head + ", size=" + size + '}';
}
public String getAll() {
System.out.println(toString());
return null;
The algorithms "in words"
Search
As for searching, you can just write a while loop in your search(String name) method that starts at the head and iterates through the list the same way you've done in your add function (where you've done:
Node c = head;
while ((c.getNextNode() != null)) {
c = c.getNextNode();
}
). But instead of stopping once the current contact being pointed to has null as it's next contact, stop when the current contact has the name you're searching for. Be careful to also stop once you have reached the end of the list in the case where you don't find the contact (so basically just add something to the existing loop condition).
Remove
As for removing an element, it's the same as searching, but with an additional step. It will be like the loop to search, but this time you'll want to stop when the next contact is the one you're looking for. Then set the 'next' reference of the current node to the node after the contact you want to remove.
I could code this up with an example, but I'll leave that to you so you will be sure to understand it :-) Good luck!
Please see explanation in Javadoc . Let me know if you have any question.
Search Method
/**
*
* #param name this the name of the contact to search for. If list has two
* contacts with same name the first one found will be used
* #return Contact
*/
public Contact search(String name) {
Node currentNode = head;
Contact contact = null;
for (int i = 0; i < size; i++) {
if (currentNode.getContact().getName().equalsIgnoreCase(name)) {
contact = currentNode.getContact();
break;
}
currentNode = currentNode.getNextNode();
}
return contact;
}
Remove Method and helper method searchNodeOneBeforeTheTargetNode
/**
*
* #param name of the contact to remove
* #return True for successful removal
*/
public boolean remove(String name) {
Node node = searchNodeOneBeforeTheTargetNode(name);
boolean removalSuccessfull = false;
if (node != null) {
node.setNextNode(node.getNextNode().getNextNode());
removalSuccessfull = true;
}
return removalSuccessfull;
}
/**
* Pay attention to this method. Since your linked list a Singly linked
* list, meaning every node only knows about the next node not the previous.
* This method return the previous node to of the target node. All that is
* needed to be done here is that we get the next node of target and
* attached that to the previous node of the target e.d if we want to remove B from below
*
* A->B->C A know B but B does not know about A it know about C . To delete B we connect A->C and B is deleted
*
*
*
* #param name
* #return
*/
private Node searchNodeOneBeforeTheTargetNode(String name) {
Node currentNode = head;
Node nodeOneBeforeTheTargetNode = null;
for (int i = 0; i < size; i++) {
if (currentNode.getContact().getName().equalsIgnoreCase(name)) {
nodeOneBeforeTheTargetNode = currentNode;
break;
}
currentNode = currentNode.getNextNode();
}
return nodeOneBeforeTheTargetNode;
}
Get All Method Note your method returns String. If you are getting all elements of linked list which are in this case contacts then it should return some collection. I am using Array as that is most basic.
/**
*
* #return Array of all contacts in linked list
*/
public Contact[] getAll() {
Contact[] contacts = new Contact[size];
Node currentNode = head;
for (int i = 0; i < size; i++) {
if (currentNode != null) {
contacts[i] = currentNode.getContact();
currentNode = currentNode.getNextNode();
}
}
return contacts;
}
I am learning Java SE and am currently at simple linked lists (page 687/1047 of Savitch's Absolute Java).
I am stuck at instantiating the LinkList in the main method of my demo class:
LinkedList1 list = new LinkedList1();
I tried using breakpoint and it indicates a ReflectiveOperationException.
This is the code:
public class Node1
{
private String item;
private int count;
private Node1 link;
public Node1()
{
link = null;
item = null;
count = 0;
}
public Node1(String newItem, int newCount, Node1 linkValue)
{
setData(newItem, newCount);
link = linkValue;
}
public void setData(String newItem, int newCount)
{
item = newItem;
count = newCount;
}
public void setLink(Node1 newLink)
{
link = newLink;
}
public String getItem()
{
return item;
}
public int getCount()
{
return count;
}
public Node1 getLink()
{
return link;
}
}
This is the LinkedList1 class:
public class LinkedList1
{
private Node1 head;
public LinkedList1()
{
head = null;
}
/**
* Adds a node at the start of the list with the specified data.
* The added node will be the first node in the list.
*/
public void add(String itemName, int itemCount)
{
head = new Node1(itemName, itemCount, head);
}
/**
* Removes the head node and returns true if the list contains at least
* one node. Returns false if the list is empty.
*/
public boolean deleteHeadNode()
{
if (head != null)
{
head = head.getLink();
return true;
}
else
return false;
}
/**
* Returns the number of nodes in the list.
*/
public int size()
{
int count = 0;
Node1 position = head;
while (position != null)
{
count++;
head = position.getLink();
}
return count;
}
public boolean contains(String item)
{
return (find(item) != null);
}
/**
* Finds the first node containing the target item, and returns a
* reference to that node. If the target is not in the list, null is returned.
*/
public Node1 find(String target)
{
Node1 position = head;
String itemAtPosition;
while(position != null)
{
itemAtPosition = position.getItem();
if(itemAtPosition.equals(target))
{
return position;
}
position = position.getLink();
}
return null; //target was not found
}
public void outputList()
{
Node1 position = head;
while (position != null)
{
System.out.println(position.getItem() + " " + position.getCount());
position = position.getLink();
}
}
}
I think that the problem has something to do with the constructor of Node1 having the member link of type Node1. I'm trying to understand how these data structures work and not just resort to using the built-in ArrayList(& APIs) for my projects. Can you guys have a look and point me in the right direction. Any help would be very much appreciated.
This is my main method.
public class LinkedListDemo
{
public static void main(String[] args)
{
try
{
LinkedList1 list = new LinkedList1();
list.add("apples", 1);
list.add("bananas", 2);
list.add("cantaloupe", 3);
System.out.println("List has "+ list.size() + " nodes.");
list.outputList();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
Your size method contains an infinite loop which explain why the outputs are never reached.
while (position != null)
{
count++;
head = position.getLink();
}
You are looping until position is null, but never assign anything to position and instead assign to head. Instead, you want to do
while (position != null)
{
count++;
position = position.getLink();
}
Now you would get the output
List has 3 nodes.
cantaloupe 3
bananas 2
apples 1
I got this assignment to create an equals method for doubly linked list. So far I got the code I posted below. It passes some of the tests, but not all. The failures do have the same expected value as the actual value, but I still get some AssertionErrors.
Ive been messing and trying to change things for quite some time now, but I cant seem to figure it out on my own. Nor can I find any good examples on the internet. I've tried using Eclipse to generate the equals method, but that too does not pass all the tests.
I know you do not give away free answers here, but could someone maybe point to the mistake in the code?
/**
* This method should return true iff the values of this list
* and that are identical and in the same order.
* #param that list to compare this to.
* #return true iff the values are identical and in the same order
*/
public boolean equals(Object that) {
if (that == null)
return false;
if (!(that instanceof DoublyLinkedList) )
return false;
DoublyLinkedList<E> other = (DoublyLinkedList<E>) that;
if (header == null&&other.header != null)
return false;
if (trailer == null&&other.trailer != null)
return false;
while (header.getNext() != trailer){
if (!(header.equals(other.header))){
return false;
}
header = header.getNext();
other.header = other.header.getNext();
}
return true;
}
Edit, per request the failed tests en DLL class:
public static class DoublyLinkedList<E> {
private Node<E> header;
private Node<E> trailer;
/**
* Constructor that creates an empty DLL
*/
public DoublyLinkedList() {
this.header = new Node<>(null, null, null);
this.trailer = new Node<>(null, header, null);
this.header.setNext(trailer);
}
/**
* #return if the list is empty.
*/
public boolean isEmpty() {
return this.header.getNext() == this.trailer;
}
/**
* #return the first element of the list.
*/
public E getFirst() {
if (isEmpty()) return null;
return this.header.getNext().getElement();
}
/**
* #return the last element of the list.
*/
public E getLast() {
if (isEmpty()) return null;
return this.trailer.getPrevious().getElement();
}
/**
* Adds a new Node to the beginning of the list,
* containing the specified value.
* #param value for the new first node to hold.
*/
public void addFirst(E element) {
Node<E> newNode = new Node<>(element, header, header.getNext());
header.getNext().setPrevious(newNode);
header.setNext(newNode);
}
/**
* This method should return true iff the values of this list
* and that are identical and in the same order.
* #param that list to compare this to.
* #return true iff the values are identical and in the same order
*/
public boolean equals(Object that) {
if (that == null)
return false;
if (!(that instanceof DoublyLinkedList) )
return false;
DoublyLinkedList<E> other = (DoublyLinkedList<E>) that;
if (header == null&&other.header != null)
return false;
if (trailer == null&&other.trailer != null)
return false;
while (header.getNext() != trailer){
if (!(header.equals(other.header))){
return false;
}
header = header.getNext();
other.header = other.header.getNext();
}
return true;
}
/**
* Simple toString for testing purposes. Please note that solutions that use the
* .toString() to implement the .equals() method will be rejected.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DoublyLinkedList<");
Node<E> finger = header.getNext();
while (finger != trailer) {
sb.append(finger.toString());
if (finger.getNext() != trailer) {
sb.append("-");
}
finger = finger.getNext();
}
sb.append(">");
return sb.toString();
}
}
And the tests:
#Test
public void testEqualsCopy() {
Solution.DoublyLinkedList<Integer> dll1 = createDLL(2);
Solution.DoublyLinkedList<Integer> dll2 = createDLL(2);
assertEquals(dll1, dll2);
}
#Test
// Both lists contain only the entry 42.
public void testTwoEqualLists() {
Solution.DoublyLinkedList<Integer> dll1 = new Solution.DoublyLinkedList<>();
Solution.DoublyLinkedList<Integer> dll2 = new Solution.DoublyLinkedList<>();
dll1.addFirst(42);
dll2.addFirst(42);
assertEquals(dll1, dll2);
}
and the errors:
testEqualsCopy(UTest) failed: 'java.lang.AssertionError: expected: Solution$DoublyLinkedList<DoublyLinkedList<1-0>> but was: Solution$DoublyLinkedList<DoublyLinkedList<1-0>>'
testTwoEqualLists(UTest) failed: 'java.lang.AssertionError: expected: Solution$DoublyLinkedList<DoublyLinkedList<42>> but was: Solution$DoublyLinkedList<DoublyLinkedList<42>>'
Since, there's quite a gap between what I think a doubly linked list should look like and what you have, I would like to add my sample implementation instead. It does away with the dummy header and trailer nodes which IMHO aren't required at all.
public class DoublyLinkedList<E> {
private Node<E> header;
private Node<E> trailer;
/**
* #return if the list is empty.
*/
public boolean isEmpty() {
return header == null;
}
/**
* #return the first element of the list.
*/
public E getFirst() {
return header != null ? header.getElement() : null;
}
/**
* #return the last element of the list.
*/
public E getLast() {
return trailer != null ? trailer.getElement() : null;
}
/**
* Adds a new Node to the beginning of the list,
* containing the specified value.
* #param value for the new first node to hold.
*/
public void addFirst(E element) {
Node<E> newNode = new Node<E>(element, null, header);
header = newNode;
if (trailer == null) {
trailer = newNode;
}
}
/**
* This method should return true if the values of this list and that are
* identical and in the same order.
*
* #param that
* list to compare this to.
* #return true if the values are identical and in the same order
*/
#SuppressWarnings("unchecked")
public boolean equals(Object that) {
if (!(that instanceof DoublyLinkedList))
return false;
DoublyLinkedList<E> other = (DoublyLinkedList<E>) that;
// if lists are empty
if (header == null) {
return other.header == null ? true : false;
}
if (!header.equals(other.header))
return false;
// Just one element
if (header == trailer) {
return true;
}
if (!trailer.equals(other.trailer))
return false;
Node<E> thisNode = header;
Node<E> otherNode = other.header;
while (thisNode.getNext() != trailer) {
thisNode = thisNode.getNext();
otherNode = otherNode.getNext();
if (!(thisNode.equals(otherNode))) {
return false;
}
}
return true;
}
/**
* Simple toString for testing purposes. Please note that solutions that use the
* .toString() to implement the .equals() method will be rejected.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DoublyLinkedList<");
Node<E> finger = header;
while (finger != null) {
sb.append(finger.toString());
if (finger.getNext() != null) {
sb.append("-");
}
finger = finger.getNext();
}
sb.append(">");
return sb.toString();
}
}
Here's what my Node class looks like. Not many changes here.
public class Node<E> {
private E element;
private Node<E> previous;
private Node<E> next;
public Node<E> getPrevious() {
return previous;
}
public Node<E> getNext() {
return next;
}
public E getElement() {
return element;
}
public Node(E element, Node<E> previous, Node<E> next) {
this.element = element;
this.previous = previous;
this.next = next;
}
#Override
#SuppressWarnings("unchecked")
public boolean equals(Object that) {
if (!(that instanceof Node)) {
return false;
}
Node<E> other = (Node<E>) that;
if (element == null) {
return other.element == null ? true : false;
}
return element.equals(other.element);
}
#Override
public String toString() {
return element.toString();
}
}
Here's the code I used to test my implementation.
DoublyLinkedList<Integer> dll1 = new DoublyLinkedList<Integer>();
dll1.addFirst(100);
dll1.addFirst(200);
DoublyLinkedList<Integer> dll2 = new DoublyLinkedList<Integer>();
dll2.addFirst(100);
dll2.addFirst(200);
DoublyLinkedList<Integer> dll3 = new DoublyLinkedList<Integer>();
dll3.addFirst(42);
DoublyLinkedList<String> blankList1 = new DoublyLinkedList<String>();
DoublyLinkedList<String> blankList2 = new DoublyLinkedList<String>();
if (blankList1.equals(blankList2)) {
System.out.println(blankList1 + " = " + blankList2);
}
if (!dll1.equals(dll3)) {
System.out.println(dll1 + " != " + dll3);
}
if (dll1.equals(dll2)) {
System.out.println(dll1 + " = " + dll2);
}
Output :
DoublyLinkedList<> = DoublyLinkedList<>
DoublyLinkedList<200-100> != DoublyLinkedList<42>
DoublyLinkedList<200-100> = DoublyLinkedList<200-100>