I was given Bag class like this
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Bag<Item> implements Iterable<Item> {
private int N; // number of elements in bag
private Node<Item> first; // beginning of bag
// helper linked list class
private class Node<Item> {
private Item item;
private Node<Item> next;
}
/**
* Initializes an empty bag.
*/
public Bag() {
first = null;
N = 0;
}
/**
* Is this bag empty?
* #return true if this bag is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns the number of items in this bag.
* #return the number of items in this bag
*/
public int size() {
return N;
}
/**
* Adds the item to this bag.
* #param item the item to add to this bag
*/
public void add(Item item) {
Node<Item> oldfirst = first;
first = new Node<Item>();
first.item = item;
first.next = oldfirst;
n++;
}
public void remove(Item item){
// currentNode is the reference to the first node in the list and to the Item
Node<Item> currentNode = first;
// if items equals the first node in the list, then first = currentNode.next which will make the first item
Node<Item> temp = currentNode;
while(temp.next != null){
temp = currentNode;
if(item.equals(currentNode.item)){
currentNode = currentNode.next;
temp.next = currentNode;
break;
}else{
currentNode = currentNode.next;
}
}
N--;
}
/**
* Returns an iterator that iterates over the items in the bag in arbitrary order.
* #return an iterator that iterates over the items in the bag in arbitrary order
*/
public ListIterator<Item> iterator() {
return new ListIterator<Item>(first);
}
// an iterator, doesn't implement remove() since it's optional
private class ListIterator<Item> implements Iterator<Item> {
private Node<Item> current;
public ListIterator(Node<Item> first) {
current = first;
}
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
As it can be seen,remove() method is an optional therefore it doesn't include the algorithm.
I wrote the remove method like this:
public void remove(Item item) {
Node<Item> currentNode = (Node<Item>) first;
Node<Item> previousNode = null;
while(currentNode != null){
if(item.equals(currentNode.item)){
if(previousNode == null) {
first = (Node<Item>) currentNode.next;
}
else {
previousNode.next = currentNode.next;
}
n--;
}
else {
previousNode = currentNode;
}
currentNode = currentNode.next;
}
}
However,
first = (Node<Item>) currentNode.next;
this line gives an "Type mismatch:Cannot convert from Bag.Node to Bag.Node" error which confuses me.
What should be done to overcome this error or is there a missing part in my remove method?
public class Bag<Item> implements Iterable<Item> {
// ...
private class Node<Item> {
// ...
}
// ...
}
This is defining two distinct type variables, both with the name Item.
If you want instances of Node to use the same type variable as the containing instance of Bag, remove the <Item> on Node:
private class Node {
I overcome this problem in this way.
public void removeAllOccurences(Item item){
Node<Item> currentNode = first;
Bag<Item> b = new Bag<Item>();
Bag<Item> reverseB = new Bag<Item>();
Node<Item> previous = new Node<Item>();
if(item.equals(first.item)){
first = currentNode.next;
N--;
currentNode = currentNode.next;
}
previous.item = currentNode.item;
b.add(previous.item);
currentNode = currentNode.next;
while(currentNode != null){
if(item.equals(currentNode.item))
{
previous.item = previous.item;
N--;
} else{
previous.item = currentNode.item;
b.add(previous.item);
}
currentNode = currentNode.next;
}
for(Item i: b)
reverseB.add(i);
this.first = reverseB.first;
}
If you want to test...
public static void main(String[] args) {
Bag<Integer> b = new Bag<Integer>();
Random rm = new Random();
for(int i =0; i < 10; i++)
b.add(rm.nextInt(3));
System.out.println("Bag before removing op: ");
for(Integer i: b)
System.out.print(" "+ i);
System.out.println("\nBag size BEFORE: "+b.size());
b.removeAllOccurences(2);
System.out.println("\nBag after removing op: ");
for(Integer i: b)
System.out.print(" "+ i);
System.out.println("\nBag size AFTER: "+b.size());
}
Output removing all occurrences of 2:
0 2 2 0 1 1 0 0 0 2
Bag size BEFORE: 10
Bag after removing op:
0 0 1 1 0 0 0
Bag size AFTER: 7
Related
I have a for-each loop in a method toString() that should iterate through elements in a generic FIFO queue (implemented using doubly linked list data structure) and concatenate the items in the queue onto the string a, which is returned to enqueue() which prints the string, which is a representation of my queue and its contents after an enqueue call. MY question is, why is the for-each not being executed/entered at all?
I tried inserting System.out.print("Hi"); inside the for-each, and it did not print. So I assume some block(s) of code is hindering it from executing properly.
// FIFOQueue is implemented using the structure double linked list (DLL)
// Generic, iterable
import java.util.Iterator;
import java.util.*;
public class FIFOQueueDLL<Item> implements Iterable<Item>{
private Node first;
private Node last;
private int length = 0;
// is the queue empty?
public boolean isEmpty(){
return length == 0;
}
private class Node{
Item item;
Node next;
Node previous;
}
// add an item
public void enqueue(Item n){
Node newnode = new Node();
newnode.item = n;
if(isEmpty()){
last = newnode;
} else {
first.previous = newnode;
}
newnode.next = first;
first = newnode;
length++;
System.out.println(this);
}
// remove and return the least recently added item
public Item dequeue(){
if(isEmpty()){
throw new NoSuchElementException();
}
Node t = last;
if(first == last){
first = null;
} else {
last.previous.next = null;
}
last = last.previous;
t.previous = null;
length--;
System.out.println(this.toString(););
return t.item;
}
public String toString(){
String a = "123";
for(Item item : this){
a = a + item;
}
return a;
}
public Iterator<Item> iterator(){
return new FIFOIterator();
}
private class FIFOIterator implements Iterator<Item>{
// Declare attribute
Node curr;
// Set attribute of node curr
public FIFOIterator(){
Node curr = first;
curr.item = first.item;
curr.next = first.next;
}
//private int i = length;
public boolean hasNext(){
return curr != null;
}
public Item next(){
Item a = curr.item;
curr = curr.next;
return a;
}
}
public static void main(String[] args){
FIFOQueueDLL<Character> c = new FIFOQueueDLL<Character>();
char b = 'b';
c.enqueue(b);
c.enqueue(b);
}
}
Expected output: 123b
123bb
Actual output: 123
123
Your FIFOIterator constructor creates a new object curr but does not set it to the field of the same class. Thus your field curr is null and hasNext returns false.
Change
// Set attribute of node curr
public FIFOIterator(){
Node curr = first;
curr.item = first.item;
curr.next = first.next;
}
to
// Set attribute of node curr
public FIFOIterator(){
this.curr = first;
}
I debugged this codeblock:
public String toString(){
String a = "123";
for(Item item : this){
a = a + item;
}
return a;
}
and saw that "this" holds the value of the String a. Do you want to change Item class to Character class instead, and call toCharArray() method on a instead of using this. This is what I am talking about:
public String toString(){
String a = "123";
for(Character item : a.toCharArray()){
a = a + item;
}
return a;
}
you will get into the loop and be able to append any new character you want. Hope this helps.
Hi I'm trying to make remove method. But I don't know How to make this right. Here is my code.
This is LinkedList.java from Algorithm fourth edition.
/**
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin
* Wayne.
* #author Robert Sedgewick
* #author Kevin Wayne
*/
public class LinkedQueue<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
/**
* Initializes an empty queue.
*/
public LinkedQueue() {
first = null;
last = null;
N = 0;
assert check();
}
/**
* Is this queue empty?
* #return true if this queue is empty; false otherwise
*/
public boolean isEmpty() {
return first == null;
}
/**
* Returns the number of items in this queue.
* #return the number of items in this queue
*/
public int size() {
return N;
}
/**
* Returns the item least recently added to this queue.
* #return the item least recently added to this queue
* #throws java.util.NoSuchElementException if this queue is empty
*/
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
return first.item;
}
/**
* Adds the item to this queue.
* #param item the item to add
*/
public void enqueue(Item item) {
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
N++;
assert check();
}
/**
* Removes and returns the item on this queue that was least recently added.
* #return the item on this queue that was least recently added
* #throws java.util.NoSuchElementException if this queue is empty
*/
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
assert check();
return item;
}
/**
* Returns a string representation of this queue.
* #return the sequence of items in FIFO order, separated by spaces
*/
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
// check internal invariants
private boolean check() {
if (N == 0) {
if (first != null) return false;
if (last != null) return false;
}
else if (N == 1) {
if (first == null || last == null) return false;
if (first != last) return false;
if (first.next != null) return false;
}
else {
if (first == last) return false;
if (first.next == null) return false;
if (last.next != null) return false;
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
// check internal consistency of instance variable last
Node lastNode = first;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
if (last != lastNode) return false;
}
return true;
}
//working properly
void reverseBystack(){
Stack<Item> s = new Stack<>();
Item item;
while (isEmpty() != true){
item = dequeue();
s.push(item);
}
while(s.isEmpty() != true){
item = s.pop();
enqueue(item);
}
}
//working properly.
void reverseBylink() {
Node prev = null;
Node current = this.first;
Node next = null;
Node temp = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
temp =first;
first = last;
last = temp;
}
//How to do this...;<..
int remove(Item item) {
Node cur = this.first;
while (cur !=null) {
if (cur.item.equals(item)) {
item = dequeue();
}
cur = cur.next;
N++;
}
return 0;
}
/**
* Returns an iterator that iterates over the items in this queue in FIFO order.
* #return an iterator that iterates over the items in this queue in FIFO order
*/
public Iterator<Item> iterator() {
return new ListIterator();
}
// an iterator, doesn't implement remove() since it's optional
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null; }
public void remove() { throw new UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
Unit tests
/**
* Unit tests the <tt>LinkedQueue</tt> data type.
*/
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
/* Working properly for reverseByStack.
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
q.reverseBystack();
System.out.println(q);
StdOut.println("(" + q.size() + " left on queue)");
*/
/*Move on to next, working properly
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
q.reverseBylink();
System.out.println(q);
StdOut.println("(" + q.size() + "left on queue)");*/
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("a");
q.enqueue("b");
q.enqueue("d");
q.enqueue("b");
q.enqueue("abba");
q.enqueue("a");
q.enqueue("z");
q.enqueue("a");
System.out.println(q);
System.out.println("Remove some of elements. and use reverseByLink");
q.remove("a");
q.remove("f");
q.remove("c");
System.out.println(q);
}
Output.
a b c a b d b abba a z a
Remove some of elements. and use reverseByLink
a b d b abba a z a
I don't know why String a is not removed and after abba.
int remove(Item item) {
if(this.first == null)
return 0;
if(this.first == item) {
// remove root item
Node node = this.first.next;
this.first.next = null;
this.first = node;
return 1;
}
Node prv = this.first;
while (prv.next != item)
prv = prv.next;
// item was not found
if(prv == null)
return 0;
Node node = prv.next.next;
prv.next.next = null;
prv.next = node;
return 1;
}
I'm fairly sure this method is wrong:
int remove(Item item) {
Node cur = this.first;
while (cur !=null) {
if (cur.item.equals(item)) {
item = dequeue();
}
cur = cur.next;
N++;
}
return 0;
}
Your dequeue method pops the front of the list. But the item you're removing might not be the front of the list.
I didn't look for more problems.
This is standard linked list stuff. Some of your textbooks should have algorithms for this. But basically, you need to keep track of the last pointer you used. Let's say you have lastPtr and currentPtr, and you determine that currentPtr needs to go.
Then lastPtr.next = currentPtr.next
It's more interesting if you're at the head. You need to recognize that and instead do first.next = currentPtr.next.
dequeue() methods is popping out items from the front , but to remove all the occurrences of any string , you need to modify your remove() method to -
void remove(Item item) {
Node cur = this.first;
Node prev = null;
if(this.first.item.equals(item)){
item = dequeue();
cur = this.first;
}
while (cur != null) {
/* if (cur.item.equals(item)) {
item = dequeue();
}*/
while(cur != null && !cur.item.equals(item)) {
prev = cur;
cur = cur.next;
}
if(cur == null)
return;
prev.next = cur.next;
cur = prev.next;
}
return ;
}
This question already has an answer here:
SLinkedList and Node in Java
(1 answer)
Closed 8 years ago.
I can't seem to figure out why it's printing repeated entries and not printing in order listed. Any thoughts. here is my code for the driver.
ScoresTest
public class ScoresTest
{
public static void main(String[] args)
{
// create
SLinkedList<GameEntry> highScores = new SLinkedList<GameEntry>();
GameEntry entry;
// create entries.
Scores rank = new Scores();
entry = new GameEntry("Rick", 234);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Steve", 121);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Jeremy", 438);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Mike", 925);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Craig", 465);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Juan", 777);
highScores = rank.add(entry,highScores);
System.out.println("The Original High Scores");
rank.print(highScores);
entry = new GameEntry("Tyler", 895);
highScores = rank.add(entry, highScores);
System.out.println("Scores after adding Tyler");
rank.print(highScores);
}
}
GameEntry
public class GameEntry
{
private String name; // name of the person earning this score
private int score; // the score value
// Constructor
public GameEntry(String n, int s)
{
name = n;
score = s;
}
// Get methods.
public String getName() { return name; }
public int getScore() { return score; }
// Return string representation.
public String toString()
{
return "(" + name + ", " + score + ")";
}
}// end class.
Scores
import Project1.SLinkedList.Node;
public class Scores
{
//add function
public SLinkedList<GameEntry> add(GameEntry rank, SLinkedList<GameEntry> scores)
{
Node<GameEntry> currentNode = scores.getFirst();
Node<GameEntry> nextNode = null;
Node<GameEntry> newNode = new Node<GameEntry>();
newNode.setElement(rank);
if(scores.getSize() == 0)
{
scores.addFirst(newNode);
}
else
{
while(currentNode != null)
{
nextNode = currentNode.getNext();
if(nextNode == null)
{
scores.addLast(newNode);
}
else
{
scores.addAfter(currentNode, newNode);
break;
}
currentNode = currentNode.getNext();
}
}
return scores;
}
// Print Format.
public void print(SLinkedList<GameEntry> scores)
{
Node<GameEntry> currentNode = scores.getFirst();
GameEntry currentEntry = currentNode.getElement();
System.out.printf("[");
for(int i = 0; i < scores.getSize(); i++)
{
System.out.printf(", %s", currentEntry.toString());
currentNode = currentNode.getNext();
currentEntry = currentNode.getElement();
}
System.out.println("]");
}
}
SLinkedList
public class SLinkedList<V> implements Cloneable
{
public static class Node<V>
{
// instance variables
private V element;
private Node<V> next;
// methods, constructor first
public Node ()
{
this (null, null); // call the constructor with two args
} // end no argument constructor
public Node (V element, Node<V> next)
{
this.element = element;
this.next = next;
} // end constructor with arguments
// set/get methods
public V getElement ()
{
return element;
}
public Node<V> getNext ()
{
return next;
}
public void setElement (V element)
{
this.element = element;
}
public void setNext (Node<V> next)
{
this.next = next;
}
} // End of nested node class
// instance variables.
protected Node<V> head, tail;
protected long size;
// Create empty constructor
public SLinkedList () {
head = null;
tail = null;
size = 0;
} // end constructor
// Add Fist method to add node to list.
public void addFirst (Node<V> node) {
// set the tail only if this is the very first node
if (tail == null)
tail = node;
node.setNext (head); //refer to head
head = node;
// adjust size.
size++;
} // end addFirst method.
// Add new node after current node. Checks to see if at tail also.
public void addAfter (Node<V>currentNode, Node<V>newNode) {
if (currentNode == tail)
tail = newNode;
newNode.setNext (currentNode.getNext ());
currentNode.setNext (newNode);
// adjust size.
size++;
} // end addAfter method.
// Add new node after the tail.
public void addLast (Node<V> node) {
node.setNext (null);
tail.setNext (node);
tail = node;
size++;
} // end addLast method
// Removes first node.
public Node<V> removeFirst () {
if (head == null)
System.err.println("Error: Attempt to remove from an empty list");
// save the one to return.
Node<V> temp = head;
head = head.getNext ();
temp.setNext(null);
size--;
return temp;
} // end method removeFirst
// remove the node at the end of the list.
public Node<V> removeLast () {
// // declare local variables/objects
Node<V> nodeBefore;
Node<V> nodeToRemove;
// make sure we have something to remove
if (size == 0)
System.err.println("Error: Attempt to remove fron an empty list");
// traverse through the list, getting a reference to the node before
// the trailer. Since there is no previous reference.
nodeBefore = getFirst ();
// potential error ?? See an analysis and drawing that indicates the number of iterations
// 9/21/10. size - 2 to account for the head and tail nodes. We want to refer to the one before the
// tail.
for (int count = 0; count < size - 2; count++)
nodeBefore = nodeBefore.getNext ();
// save the last node
nodeToRemove = tail;
// now, do the pointer manipulation
nodeBefore.setNext (null);
tail = nodeBefore;
size--;
return nodeToRemove;
} // end method removeLast
// Remove known node from list. Traverses through the list.
public void remove (Node<V> nodeToRemove) {
// declare local variables/references
Node<V> nodeBefore, currentNode;
// is there something to remove.
if (size == 0)
System.err.println("Error: Attempt to remove fron an empty list");
// Start at beginning of list.
currentNode = getFirst ();
if (currentNode == nodeToRemove)
removeFirst ();
currentNode = getLast ();
if (currentNode == nodeToRemove)
removeLast ();
// Check last two nodes.
if (size - 2 > 0) {
nodeBefore = getFirst ();
currentNode = getFirst ().getNext ();
for (int count = 0; count < size - 2; count++) {
if (currentNode == nodeToRemove) {
// remove current node
nodeBefore.setNext (currentNode.getNext ());
size--;
break;
} // end if node found
// references
nodeBefore = currentNode;
currentNode = currentNode.getNext ();
} // end loop to process elements
} // end if size - 2 > 0
} // end method remove
// Get methods
public Node<V> getFirst () { return head; }
public Node<V> getLast () { return tail; }
public long getSize () { return size; }
}
Here is my output.
The Original High Scores [, (Rick, 234), (Juan, 777), (Craig, 465),
(Mike, 925), (Jeremy, 438), (Steve, 121), (Steve, 121), (Steve, 121)]
Scores after adding Tyler [, (Rick, 234), (Tyler, 895), (Juan, 777),
(Craig, 465), (Mike, 925), (Jeremy, 438), (Steve, 121), (Steve, 121),
(Steve, 121)]
The while loop while(currentNode != null) only executes once, because the condition inside will break if the current item is NOT null. So it basically always adds the new item just after the first item.
The logic in the method add is very very wrong.
I am trying to learn Generics and Iterators in java and have created following code ->
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item>
{
private int N; // number of elements on list
private Node<Item> pre; // sentinel before first item
private Node<Item> post; // sentinel after last item
/*
* linked list node helper data type
*/
private static class Node<Item>
{
private Item item;
private Node<Item> next;
private Node<Item> prev;
}//class Node<Item> ends
/*
*construct an empty deque
*/
public Deque()
{
pre = new Node<Item>();
post = new Node<Item>();
pre.item = null;
post.item = null;
pre.prev = null;
post.next = null;
pre.next = post;
post.prev = pre;
N = 0;
}//Deque ends
/*
* is the deque empty?
*/
public boolean isEmpty()
{
//if( ((pre.next == post)&&(post.prev == pre)) || ( N == 0 ) ) return true;
if( N == 0 ) return true;
else return false;
}//isEmpty ends
/*
* return the number of items on the deque
*/
public int size()
{
return N;
}//size ends
/*
* insert the item at the front
* This is extension of Queue, so First is the location near Post Node
* pre-> <-post, pre->1<-post, pre->1,2<-post, pre->1,2,3<-post ...
* ^ ^ ^ ^ ^ ^ ^
* | | | | | | |
* initial these all are the effects of addFirst()
* condition
*/
public void addFirst(Item item)
{
//System.out.println("We are outside ListIterator - addFirst");
if( isEmpty() ) //here pre.next == post.prev
{
//System.out.println("We are inside isEmpty");
Node<Item> NewNode = new Node<Item>();
NewNode.item = item;
NewNode.next = post;
post.prev = NewNode;
NewNode.prev = pre;
pre.next = NewNode;
N++;
//System.out.println(NewNode.item);
}//if ends
else //here pre.next->1.prev & X.next->post
{
//System.out.println("We are inside !isEmpty");
Node<Item> NewNode = new Node<Item>();
Node<Item> last = post.prev;
NewNode.item = item;
NewNode.next = post;
post.prev = NewNode;
NewNode.prev = last;
last.next = NewNode;
N++;
//System.out.println(NewNode.item);
}//else ends
}//addFirst ends
/*
*insert the item at the end
* This is extension of Queue, so First is the location near Post Node
* pre-> <-post, pre->1<-post, pre->2,1<-post, pre->3,2,1<-post ...
* ^ ^ ^ ^ ^ ^ ^
* | | | | | | |
* initial these all are the effects of addLast()
* condition
*/
public void addLast(Item item)
{
//System.out.println("We are outside ListIterator - addLast");
if( isEmpty() ) //here pre.next == post.prev
{
//System.out.println("We are inside isEmpty");
Node<Item> NewNode = new Node<Item>();
NewNode.item = item;
NewNode.next = post;
post.prev = NewNode;
NewNode.prev = pre;
pre.next = NewNode;
N++;
System.out.println(NewNode.item);
}//if ends
else //here pre.next->1.prev & X.next->post
{
//System.out.println("We are inside !isEmpty");
Node<Item> NewNode = new Node<Item>();
Node<Item> last = pre.next;
NewNode.item = item;
NewNode.next = last;
pre.next = NewNode;
NewNode.prev = pre;
last.prev = NewNode;
N++;
System.out.println(NewNode.item);
}//else ends
}//addLast ends
/*
* delete and return the item at the front
* This is extension of Queue, so Last is the location near Pre Node
* pre->1,2,3<-post, pre->1,2<-post, pre->1<-post, pre-> <-post...
* ^ ^ ^ ^ ^ ^ ^
* | | | | | | |
* initial these all are the effects of removeFirst()
* condition
*/
public Item removeFirst()
{
if( isEmpty() ) throw new NoSuchElementException("Queue underflow EXIT" );
else
{
Item item = post.prev.item;
post.prev = post.prev.prev;
N--;
if( isEmpty() )
{
post.prev = pre;
pre.next = post;
N = 0;
}//if ends
return item;
}//else ends
}//removeFirst ends
/*
* delete and return the item at the end
* This is extension of Queue, so Last is the location near Pre Node
* pre->1,2,3<-post, pre->2,3<-post, pre->3<-post, pre-> <-post...
* ^ ^ ^ ^ ^ ^ ^
* | | | | | | |
* initial these all are the effects of removeLast()
* condition
*/
public Item removeLast()
{
if( isEmpty() ) throw new NoSuchElementException("Queue underflow EXIT" );
else
{
Item item = pre.next.item;
pre.next = pre.next.next;
N--;
if( isEmpty() )
{
pre.next = post;
post.prev = pre;
N = 0;
}//if ends
return item;
}//else ends
}//removeLast ends
/*
* return an iterator over items in order from front to end
* Returns an iterator that iterates over the items in this queue in FIFO order.
*/
public Iterator<Item> iterator()
{
return new ClassIterator<Item>(pre);
}//Iterator<Item> iterator() ends
// an iterator, doesn't implement remove() since it's optional
private static class ClassIterator<Item> implements Iterator<Item>
{
private Node<Item> current;
private int index = 0;
public ClassIterator(Node<Item> pre)
{
current = pre.next;
index = 1;
//System.out.println(current.item);
}
public boolean hasNext()
{
//System.out.println(current.item);
return current.next != null;
}
public void remove() { throw new UnsupportedOperationException(); }
public Item next()
{
if ( !hasNext() )
{
System.out.println("Queue is empty!!!");
throw new NoSuchElementException();
}
Item item = current.item;
current = current.next;
index++;
return item;
}
public void DisplayIndex( int indexVal )
{
if( index == indexVal ) System.out.println(current.item);
else {}
}//DisplayIndex ends
}//class ListIterator<Item> ends
public String toString()
{
StringBuilder s = new StringBuilder();
for (Item item : this) s.append(item + " ");
return s.toString();
}
/*
* Display at random based on the indices supplied from the main
*/
/*
* main function for unit testing
*/
public static void main(String[] args)
{
int N = Integer.parseInt(args[0]);
int K = Integer.parseInt(args[1]);
Deque<String> list = new Deque<String>();
System.out.println("Adding to the list by - addFirst");
for (int i = 0; i < N; i++) list.addFirst( StdIn.readString() );
StdOut.println(list);
StdOut.println();
Iterator<String> iter = list.iterator();
// print random index value
StdOut.println("Index Value = 1");
boolean a = iter.hasnext();
iter.DisplayIndex( 1 );
}//main ends
}
The problem is that i am not able to access hasnext() and DisplayIndex functions with ClassIterator even though i have created an object of Iterator. Any help ?
Check out my implemenation .... it works
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Deque<Item> implements Iterable<Item> {
private Node Head;
private Node Tail;
private int N;
private class Node{ // nested class to define nodes
Item item;
Node next;
Node previous;
}
public Deque() { // construct an empty deque
Head = null;
Tail = null;
}
public boolean isEmpty() { // is the deque empty?
return (Head == null && Tail == null);
}
public int size() { // return the number of items on the deque
return N;
}
public void addFirst(Item item) { // insert the item at the front
if(item == null)
throw new NullPointerException();
Node newNode = new Node();
newNode.item = item;
newNode.next = null;
newNode.previous = null;
if(Head == null && Tail == null) {
Head = newNode;
Tail = newNode;
}
else {
Node temp = Head;
Head = newNode;
newNode.next = temp;
temp.previous = newNode;
}
N++;
}
public void addLast(Item item) { // insert the item at the end
if(item == null)
throw new NullPointerException();
Node newNode = new Node();
newNode.item = item;
newNode.next = null;
newNode.previous = null;
if(Head == null && Tail == null) {
Head = newNode;
Tail = newNode;
}
else {
Tail.next = newNode;
newNode.previous = Tail;
Tail = newNode;
}
N++;
}
public Item removeFirst() { // delete and return the item at the front
if(isEmpty())
throw new NoSuchElementException();
Node temp = Head;
Head = Head.next;
Head.previous = null;
temp.next = null; // not required though its better to break the link
N--;
return temp.item;
}
public Item removeLast() { // delete and return the item at the end
if(isEmpty())
throw new NoSuchElementException();
Node temp = Tail;
Tail = Tail.previous;
Tail.next = null;
temp.previous = null;
N--;
return temp.item;
}
public Iterator<Item> iterator() { // return an iterator over items in order from front to end
return new dequeIterator<Item>();
}
#SuppressWarnings("hiding")
private class dequeIterator<Item> implements Iterator<Item> {
private Node current;
public dequeIterator() {
this.current = Head;
}
public boolean hasNext() {
//return ((current.next!=null)?true:false);
return current != null ;//&& current.next != null;
}
#SuppressWarnings("unchecked")
public Item next() {
if(!hasNext())
throw new NoSuchElementException();
Item temp = (Item) current.item;
current = current.next;
return temp;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public void dispForward(){
Node temp = Head; //here did not assign memory as only reference was required
while(temp!=null) {
System.out.print(temp.item+" ");
temp = temp.next;
}
}
public void dispBackward(){
Node temp = Tail; //here did not assign memory as only reference was required
while(temp!=null) {
System.out.print(temp.item+ " ");
temp = temp.previous;
}
}
public static void main(String[] args) { // unit testing
Deque<Integer> de = new Deque<Integer>();
de.addFirst(10);
de.addFirst(9);
de.addFirst(8);
de.addLast(7);
de.addLast(6);
de.dispForward();
System.out.println();
System.out.println(de.removeLast());
System.out.println(de.removeFirst());
de.dispBackward();
System.out.println();
System.out.println("usnig iterator");
// using iterator
Iterator<Integer> itr = de.iterator();
while(itr.hasNext()) {
Object element = itr.next();
System.out.print(element + " ");
}
}
}
I am writing a ordered linked list for an assignment. We are using comparable, and I am struggling to get boolean add to work properly. I have labored over this code for two weeks now, and I am going cross-eyed looking at the code. I could really appreciate a fresh set of eyes on my code.
The code should work for Comparable data - both ints and String (not mixed though). I can get close to making each work, but not one code that stands for all. Please help me fix this, so the code works for either Strings or Ints.
I am only allowed to alter the add(), remove() and OrderedListNode classes
Update Thanks to parkydr, I was able to work out some of my issues, however, I am still getting a null point error. I am testing both int and Strings. If the String loop has a "<" in the while section then elements come back in reverse order. I will be an error for ints with that though. If I have >=, like parkydr said, then I get back the ints in proper order, but Strings get a null pointer error. How do I get both to work together?
Update2 the ints need to be in order, like in the code from AmitG.
Edit Does anyone have any ideas?
package dataStructures;
/**
* Class OrderedLinkedList.
*
* This class functions as a linked list, but ensures items are stored in ascending
order.
*
*/
public class OrderedLinkedList
{
/**************************************************************************
* Constants
*************************************************************************/
/** return value for unsuccessful searches */
private static final OrderedListNode NOT_FOUND = null;
/**************************************************************************
* Attributes
*************************************************************************/
/** current number of items in list */
private int theSize;
/** reference to list header node */
private OrderedListNode head;
/** reference to list tail node */
private OrderedListNode tail;
/** current number of modifications to list */
private int modCount;
/**************************************************************************
* Constructors
*************************************************************************/
/**
* Create an instance of OrderedLinkedList.
*
*/
public OrderedLinkedList()
{
// empty this OrderedLinkedList
clear();
}
/**************************************************************************
* Methods
*************************************************************************/
/*
* Add the specified item to this OrderedLinkedList.
*
* #param obj the item to be added
*/
public boolean add(Comparable obj){
OrderedListNode node = new OrderedListNode(obj);
OrderedListNode head2 = new OrderedListNode(obj);
OrderedListNode tail2 = new OrderedListNode(obj);
if (head2 == null)
{
head2 = node;
tail2 = node;
return true;
}
// When the element to be added is less than the first element in the list
if (obj.compareTo(head2.theItem) < 0)
{
node.next = head2;
head2 = node;
return true;
}
// When the element to be added is greater than every element in in list
// and has to be added at end of the list
if (obj.compareTo(tail2.theItem) > 0)
{
tail2.next = node;
tail2 = node;
return true;
}
//When the element to be added lies between other elements in the list
if (obj.compareTo(head2.theItem) >= 0 && obj.compareTo(tail2.theItem) <= 0)
{
OrderedListNode current = head.next;
OrderedListNode previous = head;
while (obj.compareTo(current.theItem) >= 0)
{
previous = current;
current = current.next;
}
previous.next = node;
node.next = current;
}
return true;
}
/*
* Remove the first occurrence of the specified item from this
OrderedLinkedList.
*
* #param obj the item to be removed
*/
public boolean remove(Comparable obj)
{
OrderedListNode curr = head;
OrderedListNode prev = head;
while(curr != null && ! (curr.theItem.compareTo(obj) == 0)){
prev = curr;
curr = curr.next;
}
if(curr == null)
return false;
else{
prev.next = curr.next;
curr = null;
return true;
}
}
/**
* Empty this OrderedLinkedList.
*/
public void clear()
{
// reset header node
head = new OrderedListNode("HEAD", null, null);
// reset tail node
tail = new OrderedListNode("TAIL", head, null);
// header references tail in an empty LinkedList
head.next = tail;
// reset size to 0
theSize = 0;
// emptying list counts as a modification
modCount++;
}
/**
* Return true if this OrderedLinkedList contains 0 items.
*/
public boolean isEmpty()
{
return theSize == 0;
}
/**
* Return the number of items in this OrderedLinkedList.
*/
public int size()
{
return theSize;
}
/*
* Return a String representation of this OrderedLinkedList.
*
* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString()
{
String s = "";
OrderedListNode currentNode = head.next;
while (currentNode != tail)
{
s += currentNode.theItem.toString();
if (currentNode.next != tail)
{
s += ", ";
}
currentNode = currentNode.next;
}
return s;
}
/**************************************************************************
* Inner Classes
*************************************************************************/
/**
* Nested class OrderedListNode.
*
* Encapsulates the fundamental building block of an OrderedLinkedList
* contains a data item, and references to both the next and previous nodes
* in the list
*/
// TODO: Implement the nested class OrderedListNode (5 points). This nested class
// should be similar to the nested class ListNode of the class LinkedList, but
// should store a data item of type Comparable rather than Object.
public static class OrderedListNode {
Comparable theItem;
OrderedListNode next;
OrderedListNode prev;
OrderedListNode( Comparable theItem ) { this( theItem, null, null ); }
OrderedListNode( Comparable theItem, OrderedListNode prev, OrderedListNode next)
{
this.theItem = theItem;
this.next = next;
this.prev = prev;
}
Comparable getData() { return theItem; }
OrderedListNode getNext() { return next; }
OrderedListNode getPrev() { return prev; }
}
// Remove - for testing only
public static void main (String[] args)
{
OrderedLinkedList list = new OrderedLinkedList();
list.add("1");
list.add("4");
list.add("3");
list.add("33");
list.add("4");
System.out.println(list.toString());
}
}
This above code works for ints for the most part except that items are stored as strings lexically. So I need help fixing that. I also need to make this code work with Strings as well. Right now the below code works with String but not ints, it also stores in reverse order since the <= changes in the while statement. Help!
Notice that the change in sign will make Strings work (albeit in reverse order):
while (obj.compareTo(current.theItem) <= 0)
Here's my latest version of add. It does not set up the prev links (I'll leave that as an "exercise for the reader").
public boolean add(Comparable obj){
OrderedListNode node = new OrderedListNode(obj);
// When the list is empty
if (head.next == tail)
{
head.next = node;
node.next = tail;
tail.prev = node;
return true;
}
// When the element to be added is less than the first element in the list
if (obj.compareTo(head.next.theItem) < 0)
{
node.next = head.next;
head.next = node;
return true;
}
//When there is an element in the list
OrderedListNode current = head.next;
OrderedListNode previous = head;
while (current != tail && node.theItem.compareTo(current.theItem) >= 0)
{
previous = current;
current = current.next;
}
previous.next = node;
node.next = current;
return true;
}
Modified program, output will be 1,3,33,4,4
if you want output like 1,3,4,4,33 then remove line 1 and line 2 from the following program and paste following code. Add and toString methods are modified.
int currentValue = Integer.parseInt(freshNode.theItem.toString());
int tempValue = Integer.parseInt(nodeToTraverse.theItem.toString());
if(currentValue>tempValue)
Complete code
/**
* Class OrderedLinkedList.
*
* This class functions as a linked list, but ensures items are stored in
* ascending order.
*
*/
public class OrderedLinkedList {
/**************************************************************************
* Constants
*************************************************************************/
/** return value for unsuccessful searches */
private static final OrderedListNode NOT_FOUND = null;
/**************************************************************************
* Attributes
*************************************************************************/
/** current number of items in list */
private int theSize;
/** reference to list header node */
private OrderedListNode head;
/** reference to list tail node */
private OrderedListNode tail;
/** current number of modifications to list */
private int modCount;
/**************************************************************************
* Constructors
*************************************************************************/
/**
* Create an instance of OrderedLinkedList.
*
*/
public OrderedLinkedList() {
// empty this OrderedLinkedList
// clear(); //work around with this method. Removed temporarily.
}
/**************************************************************************
* Methods
*************************************************************************/
/*
* Add the specified item to this OrderedLinkedList.
*
* #param obj the item to be added
*/
public void add(Comparable obj) {
OrderedListNode freshNode = new OrderedListNode(obj);
if (head == null) {
head = freshNode;
tail = freshNode;
return;
}
OrderedListNode nodeToTraverse = head;
while(nodeToTraverse!=null)
{
int result = freshNode.theItem.compareTo(nodeToTraverse.theItem); // line 1
if(result>0) // line 2
{
if(nodeToTraverse.next==null)
{
nodeToTraverse.next=freshNode;
freshNode.prev =nodeToTraverse;
break;
}
else
{
nodeToTraverse=nodeToTraverse.next;
continue;
}
}
else
{
nodeToTraverse.prev.next = freshNode;
freshNode.prev = nodeToTraverse.prev;
freshNode.next= nodeToTraverse;
nodeToTraverse.prev=freshNode;
break;
}
}
}
/*
* Remove the first occurrence of the specified item from this
* OrderedLinkedList.
*
* #param obj the item to be removed
*/
public boolean remove(Comparable obj) {
OrderedListNode curr = head;
OrderedListNode prev = head;
while (curr != null && !(curr.theItem.compareTo(obj) == 0)) {
prev = curr;
curr = curr.next;
}
if (curr == null)
return false;
else {
prev.next = curr.next;
curr = null;
return true;
}
}
/**
* Empty this OrderedLinkedList.
*/
public void clear() {
// reset header node
head = new OrderedListNode("HEAD", null, null);
// reset tail node
tail = new OrderedListNode("TAIL", head, null);
// header references tail in an empty LinkedList
head.next = tail;
// reset size to 0
theSize = 0;
// emptying list counts as a modification
modCount++;
}
/**
* Return true if this OrderedLinkedList contains 0 items.
*/
public boolean isEmpty() {
return theSize == 0;
}
/**
* Return the number of items in this OrderedLinkedList.
*/
public int size() {
return theSize;
}
/*
* Return a String representation of this OrderedLinkedList.
*
* (non-Javadoc)
*
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
String s = "";
OrderedListNode temp = head;
while (temp != null) {
s = s + temp.theItem.toString()+",";
temp = temp.next;
}
return s.substring(0,s.lastIndexOf(",")); //this will remove last comma
// return s; //1,2,3,4,5,25,33, this will not remove last comma(,)
}
/**************************************************************************
* Inner Classes
*************************************************************************/
/**
* Nested class OrderedListNode.
*
* Encapsulates the fundamental building block of an OrderedLinkedList
* contains a data item, and references to both the next and previous nodes
* in the list
*/
// TODO: Implement the nested class OrderedListNode (5 points). This nested
// class
// should be similar to the nested class ListNode of the class LinkedList,
// but
// should store a data item of type Comparable rather than Object.
// Remove - for testing only
public static void main(String[] args) {
OrderedLinkedList list = new OrderedLinkedList();
/*list.add("1");
list.add("4");
list.add("3");
list.add("33");
list.add("5");
list.add("2");
list.add("25");*/
list.add("1");
list.add("4");
list.add("3");
list.add("33");
list.add("4");
System.out.println(list.toString());
}
private static class OrderedListNode {
Comparable data;
Comparable theItem;
OrderedListNode next;
OrderedListNode prev;
OrderedListNode(Comparable data) {
this(data, null, null);
}
OrderedListNode(Comparable data, OrderedListNode prev, OrderedListNode next) {
this.theItem = data;
this.next = next;
this.prev = prev;
}
Comparable getData() {
return data;
}
OrderedListNode getNext() {
return next;
}
OrderedListNode getPrev() {
return prev;
}
#Override
public String toString() {
return (String)theItem;
}
}
}
import java.util.*;
public class List {
private Node head;
private int manyNodes;
public List() {
head = null;
manyNodes = 0;
}
public boolean isEmpty() {
return ((head == null) && (manyNodes == 0));
}
public void add(int element) {
if (head == null) {
head = new Node(element, null);
manyNodes++;
} else {
head.addNodeAfter(element);
manyNodes++;
}
}
public boolean remove(int target) {
boolean removed = false;
Node cursor = head;
Node precursor;
if (head == null) {
throw new NoSuchElementException("Cannot remove from empty list");
}
if (head.getInfo() == target) {
head = head.getNodeAfter();
manyNodes--;
removed = true;
} else {
precursor = cursor;
cursor = cursor.getNodeAfter();
while ((cursor != null) && (!removed)) {
if (cursor.getInfo() == target) {
precursor.removeNodeAfter();
manyNodes--;
removed = true;
} else {
precursor = cursor;
cursor = cursor.getNodeAfter();
}
}
}
return removed;
}
public Node getFront() {
return head;
}
public int size() {
return manyNodes;
}
public Node listSort(Node source) {
source = head;
int largest = Integer.MIN_VALUE;
int smallest;
Node front;
while (source != null) {
if (source.getInfo() > largest) {
largest = source.getInfo();
}
source = source.getNodeAfter();
}
front = new Node(Node.find(head, largest).getInfo(), null);
remove(largest);
while (!isEmpty()) {
source = head;
smallest = Integer.MAX_VALUE;
while (source != null) {
if (source.getInfo() <= smallest) {
smallest = source.getInfo();
}
source = source.getNodeAfter();
}
remove(smallest);
front.addNodeAfter(smallest);
}
head = front.reverse(front);
source = head;
return source;
}
public void showList() {
Node cursor = head;
if (cursor == null) {
System.out.println("This list contains no items.");
} else {
while (cursor != null) {
System.out.print(cursor.getInfo() + " ");
cursor = cursor.getNodeAfter();
}
}
}
}//end class List