Implementation of the 'set' method for a linked List? - java

I am trying to implement the set method where you pass in the position in a linked list that you want and the value and the set function adds that value into the position specified in the linked list. I have implemented the set function but for some reason The last element disappears in my implementation. I would greatly appreciate any help. Thanks in advance. I would appreciate any expert eyes that will see what I am missing.
/**
* A basic singly linked list implementation.
*/
public class SinglyLinkedList<E> implements Cloneable, Iterable<E>, List<E> {
//---------------- nested Node class ----------------
/**
* Node of a singly linked list, which stores a reference to its
* element and to the subsequent node in the list (or null if this
* is the last node).
*/
private static class Node<E> {
E value;
Node<E> next;
public Node(E e)
{
value = e;
next = null;
}
}
//----------- end of nested Node class -----------
// instance variables of the SinglyLinkedList
private Node<E> head = null; // head node of the list (or null if empty)
private int size = 0; // number of nodes in the list
public SinglyLinkedList() {
} // constructs an initially empty list
// access methods
/**
* Returns the number of elements in the linked list.
*
* #return number of elements in the linked list
*/
public int size() {
return size;
}
/**
* Adds an element to the end of the list.
*
* #param e the new element to add
*/
public void addLast(E e) {
// TODO
}
/**
* Tests whether the linked list is empty.
*
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() {
return size == 0;
}
#Override
public E get(int i) throws IndexOutOfBoundsException {
Node<E> a = head;
if(i<=this.size()) {
int count = 0;
while(count < i) {
count ++;
a = a.next;
}
return a.value;
}
return null;
}
#Override
public E set(int i, E e) throws IndexOutOfBoundsException {
Node<E> current = head;
Node<E> setNode = new Node<E>(e);
if(i==0) {
this.addFirst(e);
}
else if(i==this.size){
this.addLast(e);
}
else {
for(int j=0; current != null && j < (i-1);j++) {
current = current.next;
}
Node<E> temp = current.next;
current.next = setNode;
setNode.next = temp;
}
return setNode.value;
}
// update methods
/**
* Adds an element to the front of the list.
*
* #param e the new element to add
*/
public void addFirst(E e) {
Node<E> first = new Node<>(e);
first.next = this.head;
this.head = first;
this.size++;
}
#SuppressWarnings({"unchecked"})
public boolean equals(Object o) {
// TODO
return false; // if we reach this, everything matched successfully
}
#SuppressWarnings({"unchecked"})
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
// TODO
return null;
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
* #return
*/
public String toString() {
for(int i=0;i<this.size();i++) {
System.out.println(this.get(i));
}
return "end of Linked List";
}
public static void main(String[] args) {
SinglyLinkedList <Integer> ll =new SinglyLinkedList <Integer>();
ll.addFirst(5);
ll.addFirst(4);
ll.addFirst(3);
ll.addFirst(2);
ll.set(1,0);
System.out.println(ll);
}
}

Assumptions
addLast method is missing in the code
The error could be there too
Known cause
This code is not incrementing the size inside the set method's for loop.The size is incremented in addLast(possibly) and addFirst and not incremented in other case (final else part)

It is not clear what is planned to do with set method. The way it is implemented now, it behaves more like insert, meaning that it will add new node, bit it does not increase the total count of elements (size).
It the set method is changing the value of the node, which name indicates, then this part is wrong:
else {
for(int j=0; current != null && j < (i-1);j++) {
current = current.next;
}
Node<E> temp = current.next;
current.next = setNode;
setNode.next = temp;
}
It should replace the value instead of adding the new one:
else {
for(int j=0; current != null && j < (i-1);j++) {
current = current.next;
}
current.value=e
}
Also, it looks like the index i is 1-based, while everything else is 0 based. I didn't check the code above, but the concept should be like shown.

Related

Doubly Linked List returning null at the end of list

I am trying to implement a doubly linked list, and I am testing it with an iterator. For some reason the dll returns null at the end of the list and I can't figure out why. I would greatly appreciate an expert eye to spot what I am missing. Thanks in advance
test:
void testIterator() {
DoublyLinkedList<Integer> ll = new DoublyLinkedList<>();
for(int i = 0; i < 5; ++i) ll.addLast(i);
ArrayList<Integer> buf = new ArrayList<>();
for(Integer i : ll) {
buf.add(i);
}
assertEquals("[0, 1, 2, 3, 4]", buf.toString());
}
The test returns:
expecting [0, 1, 2, 3, 4] but was [0, 1, 2, 3, 4,null]
The Doubly Linked List
import java.util.Iterator;
public class DoublyLinkedList<E> implements List<E> {
/** Sentinel node at the beginning of the list */
private Node<E> header; // header sentinel
/** Sentinel node at the end of the list */
private Node<E> trailer; // trailer sentinel
/** Number of elements in the list (not including sentinels) */
private int size = 0;
//---------------- nested Node class ----------------
/**
* Node of a doubly linked list, which stores a reference to its
* element and to both the previous and next node in the list.
*/
private static class Node<E> {
private E data;
private Node<E> next;
private Node<E> previous;
public Node(E data, Node<E> previous,Node<E> next)
{
this.data = data;
this.next = next;
this.previous = previous;
}
public E getData()
{
return data;
}
public Node<E> getNext()
{
return next;
}
public Node<E> getPrevious()
{
return previous;
}
public void setNext(Node<E> n)
{
next = n;
}
public void setPrevious(Node<E> p)
{
previous = p;
}
public void setData(E d)
{
data = d;
}
} //----------- end of nested Node class -----------
// instance variables of the DoublyLinkedList
// number of elements in the list
/** Constructs a new empty list. */
public DoublyLinkedList() {
header = new Node<>(null, null, null);
trailer = new Node<>(null, header, null);
header.setNext(trailer);
}
// public accessor methods
/**
* Returns the number of elements in the linked list.
* #return number of elements in the linked list
*/
public int size() { return size; }
/**
* Tests whether the linked list is empty.
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() { return size == 0; }
#Override
public E get(int i) throws IndexOutOfBoundsException {
if((i>size()-1) || isEmpty()) {
throw new IndexOutOfBoundsException("It is not possible to get this indexed value");
}
Node<E> current = header.getNext();
for(int j=0;j<i && current != trailer;j++) {
current = current.getNext();
}
return current.getData();
}
#Override
public E set(int i, E e) throws IndexOutOfBoundsException {
Node<E> current = header.getNext();
if (isEmpty() || i > size()-1)
{
throw new RuntimeException("cannot delete either index too big or list is empty");
}
for(int j =0; j<i;j++) {
current = current.getNext();
}
current.setData(e);
return current.getData();
}
#Override
public void add(int i, E e) throws IndexOutOfBoundsException {
if (i < 0|| i > size()-1)
{
throw new RuntimeException("cannot delete either index too big or list is empty");
}
else {
Node<E> current = header.getNext();
for(int j = 0; j< i;j++) {
current = current.getNext();
}
addBetween(e,current.getPrevious(),current);
}
}
#Override
public E remove(int i) throws IndexOutOfBoundsException {
if (isEmpty() || i > size()-1)
{
throw new RuntimeException("cannot delete either index too big or list is empty");
}
Node<E> current = header.getNext();
Node<E> previous = header;
//find the correct node to remove
for (int k = 0; k < i; k++)
{
previous = current;
current = current.getNext();
}
Node<E> next =current.getNext();
previous.setNext(next);
next.setPrevious(previous);
size--;
return current.getData();
}
#Override
public Iterator<E> iterator() {
return new DoublyLinkedListIterator();
}
private class DoublyLinkedListIterator implements Iterator<E> {
private Node<E> current;
public DoublyLinkedListIterator() {
current = header.getNext();
}
#Override
public boolean hasNext() {
return current != null;
}
#Override
public E next() {
if(!hasNext()) throw new RuntimeException("No such element");
E res = current.getData();
current = current.getNext();
return res;
}
}
/**
* Returns (but does not remove) the first element of the list.
* #return element at the front of the list (or null if empty)
*/
public E first() {
// TODO
return header.getNext().getData();
}
/**
* Returns (but does not remove) the last element of the list.
* #return element at the end of the list (or null if empty)
*/
public E last() {
// TODO
return trailer.getPrevious().getData();
}
// public update methods
/**
* Adds an element to the front of the list.
* #param e the new element to add
*/
public void addFirst(E e) {
addBetween(e,header,header.getNext());
}
/**
* Adds an element to the end of the list.
* #param e the new element to add
*/
public void addLast(E e) {
addBetween(e,trailer.getPrevious(),trailer);
}
/**
* Removes and returns the first element of the list.
* #return the removed element (or null if empty)
*/
public E removeFirst() {
Node<E> current = header.getNext();
remove(0);
return current.getData();
}
/**
* Removes and returns the last element of the list.
* #return the removed element (or null if empty)
*/
public E removeLast() {
return remove((this.size()-1));
}
// private update methods
/**
* Adds an element to the linked list in between the given nodes.
* The given predecessor and successor should be neighboring each
* other prior to the call.
*
* #param predecessor node just before the location where the new element is inserted
* #param successor node just after the location where the new element is inserted
*/
private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
Node<E> newNode = new Node(e,predecessor,successor);
predecessor.setNext(newNode);
successor.setPrevious(newNode);
this.size++;
}
/**
* Removes the given node from the list and returns its element.
* #param node the node to be removed (must not be a sentinel)
*/
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
*/
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
Node<E> current = header.getNext();
while (current.getNext() != null && current != null)
{
stringBuilder.append(current.getData());
stringBuilder.append(", ");
current = current.getNext();
}
stringBuilder.replace(stringBuilder.length()-2, stringBuilder.length(), "");
stringBuilder.append("]");
return stringBuilder.toString();
}
public static void main(String [] args) {
//ArrayList<String> all;
//LinkedList<String> ll;
DoublyLinkedList<String> ll = new DoublyLinkedList<String>();
String[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
for (String s : alphabet) {
ll.addFirst(s);
ll.addLast(s);
}
System.out.println(ll.toString());
for (String s : ll) {
System.out.print(s + ", ");
}
}
} //----------- end of DoublyLinkedList class -----------```

Why is the remove() method in my customized LinkedList not working properly?

I'm sorry if this is a very long code, but the only problem is the remove() method in the LinkedList Class, and I've been struggling on this code for hours and couldn't seem to find a solution. Whenever I input ADD 456 for the main method, instead of printing
0+6+5+4
RESULT 15
I keep on getting
0+6+6+4
RESULT 16
That means either the remove() or insert() method went wrong, but when I checked the input of the insert() method, 5 was properly inserted when it had to. So I was wondering which part of the remove() method went wrong, and how I could solve it. Thanks.
These are the interfaces.
Interface Stack.
package ds.stack;
public interface Stack<E> {
/*
* Removes all of the elements in this stack.
*/
public void clear();
/*
* Pushes an item onto the top of this stack.
*
* #param item
* the item to be pushed onto this stack
*/
public void push(E item);
/**
* Removes the item at the top of this stack and returns that item as the
* value of this method.
*
* #return the item at the top of this stack, or null if this stack is empty
*/
public E pop();
/**
* Returns the number of elements in this stack.
*
* #return the number of elements in this stack
*/
public int length();
/**
* Returns true if this stack contains no elements.
*
* #return true if this stack contains no elements
*/
public boolean isEmpty();
}
Interface List.
package ds.list;
public interface List<E> {
/**
* Removes all of the elements from this list.
*/
public void clear();
/**
* Inserts the specified element at the specified position in this list.
*
* #param pos
* index at which the specified element is to be inserted
* #param item
* element to be inserted
*/
public void insert(int pos, E item);
/**
* Removes the element at the specified position in this list. Shifts any
* subsequent elements to the left (subtracts one from their indices).
* Returns the element that was removed from the list.
*
* #param pos
* the index of the element to be removed
* #return the element previously at the specified position
*/
public E remove(int pos);
/**
* Returns the number of elements in this list.
*
* #return the number of elements in this list.
*/
public int length();
/**
* Returns the element at the specified position in this list.
*
* #param pos
* index of the element to return
* #return the element at the specified position in this list
*/
public E getValue(int pos);
}
Here is my LinkedList Class
package ds.list;
public class LinkedList<E> implements List<E> {
private E element;
private LinkedList<E> next;
private LinkedList<E> head;
private LinkedList<E> tail;
private LinkedList<E> curr;
public int cnt=0; //length of the list
/*
* constructors below
*/
public LinkedList() { //The very initial constructor
curr = tail = head = this;
}
public LinkedList(LinkedList<E> nextval) { //when you start making more bundles
next = nextval;
}
public void setNext(LinkedList<E> nextval) {
next = nextval;
}
public void goNext() {
curr = next;
} // curr becomes the next bundle
public void setValue(E item) {
element = item;
}
#Override
public void clear() {
tail = head = new LinkedList<E>();
next = null;
cnt = 0;
}
#Override
public void insert(int pos, E item) {
if(pos<0||pos>cnt+1) {
return;
}
if(pos==0) {
curr = head;
head = new LinkedList<E>(curr);
curr = head;
curr.setValue(item);
}
curr = head;
for(int i=0;i<pos-1;i++) {
goNext();
} //curr points right before the index of pos
LinkedList<E> temp = curr.next;
curr.setNext(new LinkedList<E>(temp));
curr.goNext();
curr.setValue(item);
cnt++;
}
#Override
public E remove(int pos) {
if(pos<0||pos>cnt)
return null;
curr = head;
if(cnt==1) {
E it = element;
curr = head = tail = null;
cnt--;
return it;
}
for(int i=0;i<pos-1;i++) {
goNext();
}
E it = next.element;
curr.setNext(next.next);
cnt--;
return it;
}
#Override
public int length() {
return cnt;
}
#Override
public E getValue(int pos) {
if(pos<0||pos>cnt)
return null;
curr = head;
for(int i=0;i<pos-1;i++) {
goNext();
}
return next.element;
}
}
And this is my LinkedStack Class, utilizing the LinkedList Class
package ds.stack;
import ds.list.LinkedList;
public class LinkedStack<E> implements Stack<E> {
private LinkedList<E> stack = new LinkedList<E>();
#Override
public void clear() {
stack.clear();
}
#Override
public void push(E item) {
if(stack.cnt == 0) {
stack.setValue(item);
stack.cnt++;
return;
}
stack.insert(stack.length(),item);
}
#Override
public E pop() {
if(stack.length()==0) {
return null;
}
else {
return stack.remove(stack.length()-1);
}
}
#Override
public int length() {
return stack.length();
}
#Override
public boolean isEmpty() {
if(stack.length()==0)
return true;
return false;
}
}
Then this is my BabyCalculator Class that uses the LinkedStack Class
package ds.test;
import ds.stack.LinkedStack;
import ds.stack.Stack;
public class BabyCalculator {
Stack<Character> stack = new LinkedStack<Character>();
private int value=0;
public int murmurAdd(String polynomial) {
char[] charPol=polynomial.toCharArray();
int count=0;
for(int i=0;i<polynomial.length();i++) {
if(!(Character.isDigit(charPol[i])))
count++;
} // This counts the total number of ( and )s.
int numOf=count/2;
if (numOf==0) {
for(int i=0;i<polynomial.length();i++) {
stack.push(charPol[i]);
}
}
else {
for(int i=0;i<numOf;i++) {
int num1=0, num2 = 0; //will become the index of last ( and first )
for(int j=0;j<polynomial.length();j++) {
if(charPol[j]=='(')
num1 = j;
if(charPol[j]==')') {
num2 = j;
break;
}
}
for(int index=num1+1;index<num2;index++) {
stack.push(charPol[index]);
}
StringBuilder polytemp = new StringBuilder(polynomial);
polynomial=polytemp.replace(num1, num2+1, "").toString();
}
if(polynomial.length()>0) {
charPol = polynomial.toCharArray();
for(int i=0;i<polynomial.length();i++) {
stack.push(charPol[i]);
}
}
}
System.out.print(value);
while(!(stack.isEmpty())) {
Character a = stack.pop();
System.out.println(" a is "+a);
value += Character.getNumericValue(a);
System.out.print("+"+a);
}
System.out.println();
return value;
}
public int getValue() {
// TODO Implement this method
return value;
}
public void setValue(int newValue) {
// TODO Implement this method
value = newValue;
}
}
Finally, the main() method that uses BabyCalculator.
package ds.test;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
BabyCalculator babyCalculator = new BabyCalculator();
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String command = sc.next();
if ("ADD".equals(command)) {
String equation = sc.next();
babyCalculator.murmurAdd(equation);
System.out.println("RESULT "+babyCalculator.getValue());
// TODO
} else if ("SHOW".equals(command)) {
System.out.println("VALUE "+babyCalculator.getValue());
// TODO
} else if ("CLEAR".equals(command)) {
babyCalculator.setValue(0);
System.out.println("VALUE CLEARED");
// TODO
} else if ("SET".equals(command)) {
int newValue = sc.nextInt();
babyCalculator.setValue(newValue);
System.out.println("VALUE SET TO "+babyCalculator.getValue());
// TODO
} else if ("EXIT".equals(command)) {
System.out.println("FINAL VALUE "+ babyCalculator.getValue());
return;
// TODO
}
}
sc.close();
}
}
EDIT : When I tried ADD (2345), the result was
0+5+5+5+2
RESULT 17
Which means 5 kept popping out only until it was time for 2 to pop out. Why does this keep happening?I'm assuming it's a deep pointing issue in LinkedList class.
Well, I can say with certainty that your LinkedList is not correctly implemented. You need to do unit testing of your foundational classes before you build on top of them. A basic test involving nothing more than inserting a few elements into position 0 and then trying to get the value of items in positions 0, 1, and 2 fails.
This was a basic test I wrote and it fails with NullPointerException.
LinkedList<String> list = new LinkedList<>();
list.insert(0, "A");
list.insert(0, "B");
list.insert(0, "C");
System.out.println(list.getValue(0));
System.out.println(list.getValue(1));
System.out.println(list.getValue(2));
Add more logging throughout your code, use a debugger, implement toString methods on your classes to help you find the problems.
I can tell you that your LinkedList method getValue does not work as intended. To get my test above to work I had to change from this:
for(int i=0;i<pos-1;i++) {
goNext();
}
return next.element;
to this:
for (int i = 0; i < pos; i++) {
goNext();
}
return curr.element;
The reason is because "next" refers to the next element of whatever LinkedList you called getValue on, not the next element after the current one.
I can also tell you that you have a similar bug in your goNext method of LinkedList:
public void goNext() {
curr = next;
}
should be:
public void goNext() {
curr = curr.next;
}
There are almost certainly more issues with this class, so I highly recommend you thoroughly test and debug it as this will probably solve many of your problems.
I see more issues than one. The insert is wrong, the remove is wrong (you can validate) by calling ADD twice in the same run.
One such issue is in insert I changed your code as below:
//LinkedList<E> temp = curr.next;
//curr.setNext(new LinkedList<E>(temp));
LinkedList<E> temp = new LinkedList<E>(curr.next);
temp.setValue(curr.element);
And removed the loop
for(int i=0;i<pos-1;i++) {
goNext();
}
in remove method Atleast add test works. But you have more problems at hand. I didn't test much of other usecases.

Java- Error concerning Generics

I have a class & and inner class that work together to make a linked list. The data held by the nodes, is Generic, and I somewhere along the line of my code I screwed up involving generics but I don't know where. I get 5 errors, the first one says "type LinkedList does not take parameters" which i think is weird because LinkedList is just an interface that i'm implementing. The rest of them are phrased "Object cannot be converted to E". I marked where they're occurring. I figured my assignment was right I don't know what's wrong. If you'd like me to post the interface LinkedList let me know.
public class SinglyLinkedList<E> implements LinkedList<E> {
private Node head;
private Node tail;
private int size;
public SinglyLinkedList(){
this.head = null;
this.tail = null;
this.size = 0;
}
public E get(int index) {
//Hold the data of the cur node
//and keep iterating until you hit the
//right index
int hit = 0;
Node pos = this.head;
E found = this.head.data;//////ERROR HERE
while (hit < index) {
pos = pos.next;
found = pos.data;//////ERROR HERE
hit++;
}
return found;
}
public void add (E data) {
Node last = new Node(data, null);
//If the list is empty.
if (this.head == null) {
this.head = last;
}
//Make the cur tail's next the new node
//and set the new node as the new tail.
this.tail.next = last;
this.tail = last;
this.size++;
}
public boolean add(int index, E data) {
//Cannot add if index is not valid
if ((index >= this.size) || (index < 0) ) {
return false;
}
//If index is 0, add at beginning
Node insert = new Node(data, null);
if (index == 0) {
insert.next = this.head;
this.head = insert;
this.size++;
return true;
} else {
//Else, go until you reach desired index then
//Set whatever was at that index to the new Node's
//next value.
int hit = 1;
Node cur = this.head;
while (hit < index) {
cur = cur.next;
hit++;
}
insert.next = cur;
this.size++;
return false;
}
}
public void addAll(Collection<? extends E> c) {
for (E item: c) {
this.add(item);
}
}
public boolean contains(E data) {
int hit = 0;
Node cur = this.head;
Node move;
while (hit < this.size) {
if (data.equals(cur.data)) {
return true;
} else {
move = cur.next;
cur = move;
}
}
return false;
}
public boolean containsAll(Collection<? extends E> c) {
for (E item: c) {
if (!(this.contains(item))) {
return false;
}
}
return true;
}
public boolean remove(E data) {
Node prev = this.head;
Node cur = this.head.next;
int hit = 1;
if (!(this.contains(data))) {
return false;
} else if (data.equals(head.data)) {
this.head = cur;
return true;
this.size--;
}
while (hit < this.size) {
if (data.equals(cur.data)) {
prev.next = cur.next;
return true;
this.size--;
}
hit++;
}
}
public E remove(int index) {
int hit = 1;
E data;
Node prev = this.head;
Node cur = this.head.next;
if (index == 0) {
data = head.data; //////ERROR HERE
this.head = cur;
return data;
this.size--;
} else {
while (hit < this.size) {
if ( hit == index) {
data = cur.data; //////ERROR HERE
prev.next = cur.next;
return data;
this.size--;
} else {
prev = cur;
cur = prev.next;
hit++;
}
}
}
}
public boolean removeAll(Collection<? extends E> c) {
int prevSize = this.size;
for (E item: c) {
remove(item);
}
return (prevSize < this.size);
}
public int size() {
return this.size;
}
public boolean isEmpty() {
return (this.head == null);
}
public void clear() {
this.head = null;
this.tail = null;
size = 0;
}
private class Node<E> {
private E data;
private Node next;
private Node(E data, Node next) {
this.data = data;
this.next = next;
}
}
}
This is the interface class
/**
* The LinkedList interface defines a set of standard operations that are
* typically associated with linked list, such as adding, removing, and checking
* to see if the list contains an item.
*
* Note that while your linked list implementation should make use of a Node
* class, the methods below take in and return instances of the generic type,
* not the nodes themselves.
*
* #author Justin Nieto
* #version 1.1
* #param <E> the type of the elements to store in the linked list
*/
public interface LinkedList<E> {
/**
* Returns the element in the linked list at the specified index.
* Does not change the contents of the list in any way. If the given
* index is negative or greater than the maximum possible index, returns
* null.
*
* #param index of element to be retrieved
* #return the element at the given index or null if index out of bounds
*/
E get(int index);
/**
* Adds the specified piece of data to the end of the linked list.
* This method should execute in O(1) (constant) time. This means that
* you should not iterate over the whole list to add the item to the end
* (we will check for this).
*
* #param data the object to be added to the linked list
*/
void add(E data);
/**
* Adds given piece of data to the linked list at the given index.
* All items that were originally at the index or after the index should
* be shifted down by one. If the index specified is not valid, returns
* false. Otherwise, returns true.
*
* If the index specified is 0 or if it is one larger than the maximum
* current index (ie if index is equal to the size of the linked list),
* then this method should execute in O(1) (constant) time. This means that
* you should not iterate over the entire list to add the element, as it
* is unnecessary to do so.
*
* #param index the index at which to add the item
* #param data the item to be added to te linked list
* #return true if the data could be added at the given index
*/
boolean add(int index, E data);
/**
* Adds each element in the Collection to the end of the linked list.
*
* #param c the collection of items to add to the end of the linked list
*/
void addAll(Collection<? extends E> c);
/**
* Determines whether or not the given piece of data is in the linked list.
*
* #param data the item to check
* #return true if the linked list contains the item, false otherwise
*/
boolean contains(E data);
/**
* Determines whether or not every element of the given Collection is
* in the linked list.
*
* #param c the Collection of elements to check
* #return true if list contains every element in the Collection
*/
boolean containsAll(Collection<? extends E> c);
/**
* Finds the first element of the list equal to the given piece of data
* and removes it from the list. Returns false if the given piece of data
* is not in the list and therefore cannot be removed.
*
* #param data the piece of data to be removed from the list
* #return true if the item was removed, false if list does not contain it
*/
boolean remove(E data);
/**
* Removes and returns the item in the list at the given index.
* All items at indices after the given index are shifted down by one.
*
* #param index the index of the item to remove from the linked list
* #return the removed item
*/
E remove(int index);
/**
* Removes each element in the given collection from the linked list.
*
* #param c the Collection of items to remove
* #return true if each element in the Collection was removed.
*/
boolean removeAll(Collection<? extends E> c);
/**
* Returns the number of elements in the linked list. This method
* should execute in O(1) (constant) time. This means that you should not
* iterate over the entire list to count the number of items, but rather
* you should maintain a size variable that you can just return here.
*
* #return the number of elements in the linked list
*/
int size();
/**
* Returns true if the linked list has no elements.
*
* #return true if the list is empty, false otherwise
*/
boolean isEmpty();
/**
* Removes all elements from the list. After calling this method,
* the isEmpty method should return true.
*/
void clear();
}
Node is an inner class of SinglyLinkedList, so it already shares the type parameter E. Therefore you could make Node a non-generic class.
private class Node {
private E data;
private Node next;
private Node(E data, Node next) {
this.data = data;
this.next = next;
}
}
That removes many of the problems, because before Node was a generic class and you were using Node without a type parameter.
An alternative solution is to make Node a static nested class. This means that an instance of Node does not belong to an instance of SinglyLinkedList. Because of this, a static version of Node would need its own type parameter.
private static class Node<E> {
private E data;
private Node<E> next;
private Node(E data, Node<E> next) {
this.data = data;
this.next = next;
}
}
Notice that in this version, Node is generic, so I had to add <E> after it every time it appeared. If you go with the static approach, you will have to add <E> after every occurrence of Node in the rest of the class. There are lots of these.
Finally, the message "LinkedList does not take parameters" is self-explanatory. Presumably it says interface LinkedList when it should say interface LinkedList<E>.

Creating a Hot Potato game with collections

Hot Potato Game: In this program you are expected to implement a
general simulation of the Hot Potato game. In this game children line
up in a circle and pass an item from neighbor to neighbor as fast as
they can. At a certain point in the game, the action is stopped and
the child who has the item (the potato) is removed from the circle.
Play continues until only one child is left. In your implementation
user should input a list of names and a constant num. Your program
must return the name of the last person remaining after repetitive
counting by num.
I needed to do that but i couldn't find out how to stop that while loop in the enqueuer() method of hotpotato class. If i have some other mistakes can you please tell me?
hotpotato class:
import java.util.*;
public class hotpotato
{
private static Scanner input1 = new Scanner(System.in);
private static NodeQueue<String> potato = new NodeQueue<String>();
private static Scanner input = new Scanner(System.in);
static int num;
public static void main(String[] args)
{
System.out.println("Enter names of the children.");
enqueuer(input1.next());
System.out.println("Enter the num");
num = input.nextInt();
potatothrower();
}
public static void enqueuer(String p)
{
String keyboard = input1.next();
while(!keyboard.equals("stop"))
{
potato.enqueue(p);
}
}
public static void potatothrower()
{
for(int i = 0; i< num; i++)
{
if(!potato.isEmpty()){
String tmp = potato.front();
potato.dequeue();
potato.enqueue(tmp);
}
else{
System.out.println("Queue is empty");
}
}
potato.dequeue();
}
}
Node Class:
public class Node<E> {
// Instance variables:
private E element;
private Node<E> next;
/** Creates a node with null references to its element and next node. */
public Node() {
this(null, null);
}
/** Creates a node with the given element and next node. */
public Node(E e, Node<E> n) {
element = e;
next = n;
}
// Accessor methods:
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
// Modifier methods:
public void setElement(E newElem) {
element = newElem;
}
public void setNext(Node<E> newNext) {
next = newNext;
}
}
NodeQueue Class:
public class NodeQueue<E> implements Queue<E> {
protected Node<E> head;
protected Node<E> tail;
protected int size; // number of elements in the queue
public NodeQueue() { // constructs an empty stack
head = null;
tail = null;
size = 0;
}
public void enqueue(E elem) {
Node<E> node = new Node<E>();
node.setElement(elem);
node.setNext(null); // node will be new tail node
if (size == 0)
head = node; // special case of a previously empty queue
else
tail.setNext(node); // add node at the tail of the list
tail = node; // update the reference to the tail node
size++;
}
public E dequeue() {
if (size == 0)
System.out.println("Queue is empty.");
E tmp = head.getElement();
head = head.getNext();
size--;
if (size == 0)
tail = null; // the queue is now empty
return tmp;
}
public int size() { return size; }
public boolean isEmpty() {
return size == 0;
}
public E front() {
if (isEmpty()) System.out.println("Queue is empty.");
return head.getElement();
}
public String toString() {
Node<E> temp = head;
String s;
s = "[";
for (int i = 1; i <= size(); i++){
if(i==1)
s += temp.getElement();
else
s += ", " + temp.getElement();
temp = temp.getNext();
}
return s + "]";
}
}
Queue interface:
public interface Queue<E> {
/**
* Returns the number of elements in the queue.
* #return number of elements in the queue.
*/
public int size();
/**
* Returns whether the queue is empty.
* #return true if the queue is empty, false otherwise.
*/
public boolean isEmpty();
/**
* Inspects the element at the front of the queue.
* #return element at the front of the queue.
* #exception EmptyQueueException if the queue is empty.
*/
public E front();
/**
* Inserts an element at the rear of the queue.
* #param element new element to be inserted.
*/
public void enqueue (E element);
/**
* Removes the element at the front of the queue.
* #return element removed.
* #exception EmptyQueueException if the queue is empty.
*/
public E dequeue();
}
call:
System.out.println("Enter names of the children.");
enqueuer();
You're doing the read data only once and then enters an infinite WHILE loop because you have no way to write "stop". Therefore the function would be:
public static void enqueuer()
{
String p;
do {
p = input1.next();
if (!p.equals("stop"))
potato.enqueue(p);
} while(!p.equals("stop"));
}
The problem is really easy, just look better at your code:
public static void enqueuer(String p)
{
String keyboard = input1.next();
while(!keyboard.equals("stop"))
{
potato.enqueue(p);
}
}
You get the new input before the while. This means that keyboard will be the first argument, say Alice.
So, while alice != stop, do potato.enqueue.(p).
But since you get no new input inside the while, keyboard will ever be != then stop!
Bonus:
There is a bug i think:
public static void enqueuer(String p)
{
String keyboard = input1.next();
while(!keyboard.equals("stop"))
{
potato.enqueue(p); //you dont insert the keyboard value, but you insert every time p!
}
}

Java Iterator for circular linked list

I've created a CircularLinkedList class, instead of using the util LinkedList class. The problem is based off of the Josephus problem, stating that for a circle of 20 people, each 12th person is to be killed until it is determined which position the survivor will be left standing in (using an Iterator). I'm confused as to how I could use an Iterator with this problem, since I'm using my own class instead of LinkedList, which already has an iterator() method so that I could declare an Iterator like this:
Iterator<E> iter = cll.iterator();
I have no idea how I would write my own Iterator method, and I feel like I have to be over thinking this. Any help is appreciated! I can post my code if it would clear anything up that I forgot to mention
I'm still stuck on this, so I figured I'd post my code to see if anyone can help. It's a lot, so I apologize.
Itr class (Iterator)
import java.util.Iterator;
public class Itr<E> extends CircularLinkedList<E> implements Iterator<E>
{
/** the size of the list */
private int size = 0;
/** for the hasNext() method for Iterator */
private int nextNode = 0;
/** two Nodes used for next() method for Iterator */
private Node<E> lastReturned = null;
private Node<E> nextUp;
/** part of the Iterator implementation */
public boolean hasNext()
{
return nextNode < size;
}
/** part of the Iterator implementation */
public E next()
{
lastReturned = nextUp;
nextUp = nextUp.getNext();
nextNode++;
return lastReturned.data;
}
/** part of the Iterator implementation */
public void remove()
{
Node<E> lastNext = lastReturned.getNext();
if (lastReturned == null)
nextUp = lastNext;
else
nextNode--;
lastReturned = null;
}
}
Josephus class
public class Josephus<E>
{
public static void main(String[] args)
{
CircularLinkedList cll = new CircularLinkedList();
Itr iter = cll.iterator();
int lastMan = 0;
int n = 20;
int passes = 12;
while(n > 1)
{
iter.next();
for(int i = 0; i < n; i += passes)
{
iter.hasNext();
iter.remove();
if(n == 1)
lastMan = n;
}
}
System.out.println("Survior: " + lastMan);
}
}
CircularLinkedList class
public class CircularLinkedList<E>
{
public class Node<E>
{
/* data value **/
public E data;
/* the link **/
private Node<E> next = null;
/** constructs a Node with given data and link
* #param data the data value
* #param next the link
*/
public Node(E data, Node<E> next)
{
this.data = data;
this.next = next;
}
/** construct a Node with given data value
* #param data the data value
*/
public Node(E data)
{
this.data = data;
}
/** return the data value of a Node
* #return the data value
*/
public E getData()
{
return data;
}
/** set the next Node in a list
* #param append the data value that the new Node will contain
*/
public void setNext(Node append)
{
next = append;
}
/** return the next Node
* # return the next Node
*/
public Node<E> getNext()
{
if(current.next == null)
current.next = current;
return next;
}
}
/** a reference into the list */
private Node<E> current = null;
/** the size of the list */
private int size = 0;
/** helper methods */
/** remove the first occurance of element item.
* #param item the item to be removed
* #return true if item is found and removed; otherwise, return false.
*/
public void removeItem(E item)
{
Node<E> position = current;
Node<E> nextPosition1,
nextPosition2;
while (position.next != null)
{
if(position.getNext().getData().equals(item))
{
nextPosition1 = position.getNext();
nextPosition2 = nextPosition1.getNext();
position.setNext(nextPosition2);
}
else
{
position = position.getNext();
}
}
}
/** set the first Node in a list
* #param append the data value that the new Node will contain
*/
public void addFirst(E append)
{
current = new Node<E>(append, current);
size++;
}
/** add a new Node as the last in the List
* #param data value of the new Node
*/
public void addNext(E value)
{
// location for new value
Node<E> temp = new Node<E>(value,null);
if (current != null)
{
// pointer to possible tail
Node<E> finger = current;
while (finger.next != null)
{
finger = finger.next;
}
finger.setNext(temp);
} else current = temp;
size++;
}
/** return the data value of the fourth Node in the list
* #return the data value
*/
public E printFourth()
{
current.next.next.next = current;
return current.next.next.next.getData();
}
/** return the size of the LinkedList
* #return the size
*/
public int size()
{
return size;
}
public E get(int index)
{
Node<E> temp = null;
for(int i = 0; i < index; i++)
{
temp = current.next;
System.out.print(temp.getData() + " ");
}
return temp.getData();
}
public Itr<E> iterator()
{
return new Itr<E>();
}
#Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("[");
Node<E> aux = this.current;
boolean isFirst = true;
while(aux != null)
{
if(!isFirst)
{
sb.append(", ");
}
isFirst = false;
sb.append(aux.data.toString());
aux=aux.next;
}
return sb.append("]").toString();
}
}
I'm getting a NullPointerException from the next() method in the Itr class on the line
nextUp = nextUp.getNext();
Am I doing something wrong in the CircularLinkedList class for it to not actually be circular or is there a problem with my driver/Itr classes? I'm kind of lost at this point. Any help is appreciated.
Create a custom class which implements Iterator and return the custom Iterator from your CLL.iterator method.
See LinkedList#ListItr for inspiration - but only conside the Iterator methods (next, hasNext, remove) for this exercise. A true circular linked-list will simply follow the next node, always, and has no end - hasNext will always return true if there is at least one element. If your CLL implementation has an "end", then make sure to "move back to the start" when it is encountered.
In addition, the CLL class should conform to Iterable, which means it has an iterator method to obtain an Iterator.

Categories