I have stuck with making remove() - java

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 ;
}

Related

swap two nodes in singly linked lists using method in java

package linkedlists;
public class SinglyLinkedList<E> implements Cloneable {
//---------------- 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> {
/** The element stored at this node */
private E element; // reference to the element stored at this node
/** A reference to the subsequent node in the list */
private Node<E> next; // reference to the subsequent node in the list
/**
* Creates a node with the given element and next node.
*
* #param e the element to be stored
* #param n reference to a node that should follow the new node
*/
public Node(E e, Node<E> n) {
element = e;
next = n;
}
// Accessor methods
/**
* Returns the element stored at the node.
* #return the element stored at the node
*/
public E getElement() { return element; }
/**
* Returns the node that follows this one (or null if no such node).
* #return the following node
*/
public Node<E> getNext() { return next; }
// Modifier methods
/**
* Sets the node's next reference to point to Node n.
* #param n the node that should follow this one
*/
public void setNext(Node<E> n) { next = n; }
} //----------- end of nested Node class -----------
// instance variables of the SinglyLinkedList
/** The head node of the list */
private Node<E> head = null; // head node of the list (or null if empty)
/** The last node of the list */
private Node<E> tail = null; // last node of the list (or null if empty)
/** Number of nodes in the list */
private int size = 0; // number of nodes in the list
/** Constructs an initially empty 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; }
/**
* Tests whether the linked list is empty.
* #return true if the linked list is empty, false otherwise
*/
public boolean isEmpty() { return size == 0; }
/**
* 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() { // returns (but does not remove) the first element
if (isEmpty()) return null;
return head.getElement();
}
/**
* 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() { // returns (but does not remove) the last element
if (isEmpty()) return null;
return tail.getElement();
}
// update methods
/**
* Adds an element to the front of the list.
* #param e the new element to add
*/
public void addFirst(E e) { // adds element e to the front of the list
head = new Node<>(e, head); // create and link a new node
if (size == 0)
tail = head; // special case: new node becomes tail also
size++;
}
/**
* Adds an element to the end of the list.
* #param e the new element to add
*/
public void addLast(E e) { // adds element e to the end of the list
Node<E> newest = new Node<>(e, null); // node will eventually be the tail
if (isEmpty())
head = newest; // special case: previously empty list
else
tail.setNext(newest); // new node after existing tail
tail = newest; // new node becomes the tail
size++;
}
/**
* Removes and returns the first element of the list.
* #return the removed element (or null if empty)
*/
public E removeFirst() { // removes and returns the first element
if (isEmpty()) return null; // nothing to remove
E answer = head.getElement();
head = head.getNext(); // will become null if list had only one node
size--;
if (size == 0)
tail = null; // special case as list is now empty
return answer;
}
#SuppressWarnings({"unchecked"})
public boolean equals(Object o) {
if (o == null) return false;
if (getClass() != o.getClass()) return false;
SinglyLinkedList other = (SinglyLinkedList) o; // use nonparameterized type
if (size != other.size) return false;
Node walkA = head; // traverse the primary list
Node walkB = other.head; // traverse the secondary list
while (walkA != null) {
if (!walkA.getElement().equals(walkB.getElement())) return false; //mismatch
walkA = walkA.getNext();
walkB = walkB.getNext();
}
return true; // if we reach this, everything matched successfully
}
#SuppressWarnings({"unchecked"})
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
// always use inherited Object.clone() to create the initial copy
SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone(); // safe cast
if (size > 0) { // we need independent chain of nodes
other.head = new Node<>(head.getElement(), null);
Node<E> walk = head.getNext(); // walk through remainder of original list
Node<E> otherTail = other.head; // remember most recently created node
while (walk != null) { // make a new node storing same element
Node<E> newest = new Node<>(walk.getElement(), null);
otherTail.setNext(newest); // link previous node to this one
otherTail = newest;
walk = walk.getNext();
}
}
return other;
}
public int hashCode() {
int h = 0;
for (Node walk=head; walk != null; walk = walk.getNext()) {
h ^= walk.getElement().hashCode(); // bitwise exclusive-or with element's code
h = (h << 5) | (h >>> 27); // 5-bit cyclic shift of composite code
}
return h;
}
/**
* Produces a string representation of the contents of the list.
* This exists for debugging purposes only.
*/
public String toString() {
StringBuilder sb = new StringBuilder("(");
Node<E> walk = head;
while (walk != null) {
sb.append(walk.getElement());
if (walk != tail)
sb.append(", ");
walk = walk.getNext();
}
sb.append(")");
return sb.toString();
}
public void swapNodes(Node<E> num1, Node<E> num2) {
Node<E> num1Prev = this.head;
Node<E> num2Prev = this.head;
if (num1 == num2 )
return ;
while((num1Prev != null)&&(num1Prev.getNext() != num1)){
num1Prev = num1Prev.getNext();
}
while((num2Prev != null)&&(num2Prev.getNext() != num2)){
num2Prev = num2Prev.getNext();
}
if(num2Prev == num1) {
num1.setNext(num2.getNext());
num2.setNext(num1);
num1Prev.setNext(num2);
}
else if(num1Prev == num2) {
num2.setNext(num1.getNext());
num1.setNext(num2);
num2Prev.setNext(num1);
}
else {
Node<E> tmp = num1.getNext();
num1.setNext(num2.getNext());
num2.setNext(tmp);
num1Prev.setNext(num2);
num2Prev.setNext(num1);
}
}
//main method
public static void main(String[] args)
{
SinglyLinkedList<String> list = new SinglyLinkedList<String>();
list.addFirst("MSP");
list.addLast("ATL");
list.addLast("BOS");
//
list.addFirst("LAX");
System.out.println(list);
//
SinglyLinkedList<String> swap = new SinglyLinkedList<String>();
swap.addFirst("1");
swap.addLast("2");
swap.addLast("3");
swap.addLast("4");
swap.addLast("5");
System.out.println("Original list: " + swap);
swap.swapNodes("2","5");
System.out.println("After Swapping list: " + swap);
}
}
Task: In this exercise, you will add a method swapNodes to SinglyLinkedList class from week 2 lecture examples. This method should swap two nodes node1 and node2 (and not just their contents) given references only to node1 and node2. The new method should check if node1 and node2 are the same nodes, etc. Write the main method to test the swapNodes method. Hint: You may need to traverse the list.
I made this method
public void swapNodes(Node<E> num1, Node<E> num2) {
Node<E> num1Prev = this.head;
Node<E> num2Prev = this.head;
if (num1 == num2 )
return ;
while((num1Prev != null)&&(num1Prev.getNext() != num1)){
num1Prev = num1Prev.getNext();
}
while((num2Prev != null)&&(num2Prev.getNext() != num2)){
num2Prev = num2Prev.getNext();
}
if(num2Prev == num1) {
num1.setNext(num2.getNext());
num2.setNext(num1);
num1Prev.setNext(num2);
}
else if(num1Prev == num2) {
num2.setNext(num1.getNext());
num1.setNext(num2);
num2Prev.setNext(num1);
}
else {
Node<E> tmp = num1.getNext();
num1.setNext(num2.getNext());
num2.setNext(tmp);
num1Prev.setNext(num2);
num2Prev.setNext(num1);
}
}
And then, created an instance to check if it's work, but it is showing me an error on here swap.swapNodes("2", "5");
Does anyone know what is the problem? Thank you
It's throwing error, because in your swapNodes function, you expect two parameters of type Node<E> passed, but you are passing E (String). So you have to change signature of the function or pass Node<E> that you added to your List.
Here's how you could do your swapNodes function with parameters of type E:
public void swapNodes(E element1, E element2) {
if (element1 == element2 || element1 == null || element2 == null || isEmpty()) return;
Node<E> num1 = findNode(element1);
Node<E> num2 = findNode(element2);
if (num1 == null || num2 == null) return;
Node<E> num1Prev = this.head;
Node<E> num2Prev = this.head;
while(num1Prev != null && num1Prev.getNext() != num1){
num1Prev = num1Prev.getNext();
}
while(num2Prev != null && num2Prev.getNext() != num2){
num2Prev = num2Prev.getNext();
}
if (num1Prev.getNext() == null || num2Prev.getNext() == null) return;
if (num2Prev.equals(num1)) {
num1.setNext(num2.getNext());
num2.setNext(num1);
num1Prev.setNext(num2;
} else if (num1Prev.equals(num2)) {
num2.setNext(num1.getNext());
num1.setNext(num2);
num2Prev.setNext(num1);
} else {
Node<E> tmp = num1.getNext();
num1.setNext(num2.getNext());
num2.setNext(tmp);
num1Prev.setNext(num2);
num2Prev.setNext(num1);
}
}
The findNode function could look like this:
public Node<E> findNode(E element) {
if (isEmpty()) return null;
Node<E> node = this.head;
while(node != null) {
if (node.getElement() == element) return node;
}
return null;
}

Bag remove() method

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

Generics, Iterator -> cannot access the inner class function

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 + " ");
}
}
}

Add elements between nodes Ordered LinkedList

I queried the search engine on this site, but I did not see anything that matched what I am looking for, so I hope this question has not already been answered elsewhere. I am trying to perfect my add method for an ordered LinkedList. The rest of the program runs fine, and while the list prints out as specified in the test harness, I want the names to be sorted.
My output is this after several calls to add and remove from the harness:
Sue, Bill, Michael, Someguy, Michael, Carl, Steve, Carl, Sue
Sue, Bill, Someguy, Michael, Steve, Carl, Sue
Sue, Bill, Someguy, Michael, Steve, Carl, Sue, Sue, Bill
What I want is this:
Sue, Sue, Bill, Michael, Michael, Carl, Carl, Steve, etc...
My add method:
public boolean add(Comparable obj)
{
OrderedListNode newNode = new OrderedListNode(obj, null, null);
if( tail == null) {
tail = newNode;
head = tail;
modCount++;
return true;
}
if(((Comparable)(head.theItem)).equals(obj)){
tail.previous = newNode;
modCount++;
return true;
}else{
tail.previous.next = newNode;
newNode.previous = tail.previous;
newNode.next = tail;
tail.previous = newNode;
modCount++;
return true;
}
}
Entire Code, since it was asked for:
package dataStructures;
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 newNode = new OrderedListNode(obj, null, null);
if( tail == null) {
tail = newNode;
head = tail;
modCount++;
return true;
}
if(((Comparable)(head.theItem)).compareTo(obj) > 0){
////////////////////////////////////////
//here is where my problem lies, I believe
/////////////////////////////////////////
modCount++;
return true;
}else{
tail.previous.next = newNode;
newNode.previous = tail.previous;
newNode.next = tail;
tail.previous = newNode;
modCount++;
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)
{
if(head == null) return false;
if(((Comparable)(head.theItem)).compareTo(obj) == 0) {
if(head == tail) {
head = tail = null;
return true;
}
head = head.next;
return true;
}
if(head == tail)return false;
OrderedListNode ref = head;
while( ref.next != tail) {
if(((Comparable)(ref.next.theItem)).compareTo(obj) == 0) {
ref.next = ref.next.next;
return true;
}
ref = ref.next;
}
if(((Comparable)(tail.theItem)).compareTo(obj) == 0 ) {
tail = ref;
tail.next = null;
return true;
}
return false;
}
/**
* 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;
}
private static class OrderedListNode<Comparable> {
Comparable theItem;
OrderedListNode<Comparable> next;
OrderedListNode<Comparable> previous;
public OrderedListNode(Comparable theItem, OrderedListNode<Comparable> previous, OrderedListNode<Comparable> next) {
this.theItem = theItem;
this.next = next;
this.previous = previous;
}
}
}
This line is definitely wrong
if(((Comparable)(head.theItem)).equals(obj)) {
you should use Comparable.compareTo, besides you should always start from head and go until you find an element greater or equal to obj and insert obj before it, something like this
public boolean add(Comparable obj) {
modCount++;
if (head == null) {
head = new OrderedListNode(obj, null, null);
return true;
}
for (OrderedListNode current = head; current != null; current = current.next) {
if (((Comparable) (current.theItem)).compareTo(obj) >= 0) {
current.prev = new OrderedListNode(obj, current.prev, current);
return true;
}
}
tail.next = new OrderedListNode(obj, tail, null);
return true;
}

Sorted Linked List using comparable in Java

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

Categories