I have created a queue implementation using a single connection list.In this code I am using 2 pointers (first,last) to define the start and the end of my queue. My code is :
import java.io.PrintStream;
import java.util.*
/**
* #author Justin Bieber
*/
public class StringQueueImpl<T> implements StringQueue {
private int total; // number of elements on queue
private Node head; // beginning of queue
private Node tail; // end of queue
private class Node {
T ele;
Node next;
Node(T ele) {
this.ele = ele;
next = null; }
}
/**
* Creates an empty queue.
*/
public StringQueueImpl() {
first = null;
last = null;
total = 0;
}
boolean isEmpty() {
return (head == null);
}
public <T> void put(T ele) {
Node t = tail;
tail = new Node(ele);
if (isEmpty()) head = tail;
else t.next = tail;
total++;
}
public T get() {
if (isEmpty()) throw new NoSuchElementException();
T v = head.ele;
Node t = head.next;
head = t;
return v;
total--;
}
public T peek() {
if (isEmpty()) throw new NoSuchElementException();
return head.ele;
}
Node node = head;
public void printQueue(PrintStream stream){
while(node != null){
stream.println(node.ele);
stream.flush();
node = node.next;
}
}
public int size(){
return total;
}
}
My question is how can I create a queue implementation using a circular list. (Instead of 2 pointers for the start and the end I would like to use only one pointer wich will be used for both the start and the end of the queue).
Any help is apreciated . Thank you
Related
I have made my own implementation of a generic Linked Queue for class, it is pretty much finished, here it is:
public class LinkedQueue<T> implements Queue<T> {
//Using head & tail approach.
private myNode<T> head;
private myNode<T> tail;
private int size;
public LinkedQueue(){
this.head = null;
this.tail = head;
this.size = 0;
}
public myNode<T> getterHead(){ //couldn't bring myself to write "get" instead of "getter"
return this.head;
}
#Override
public int size() {
return this.size; //returns number of nodes
}
#Override
public boolean isEmpty() {
return this.head==null;
}
#Override
public void enqueue(T element) {
if(isEmpty()){
this.head = new myNode<T>(element);
this.tail = head;
size++;
}
else{
this.tail.next = new myNode<T>(element);
this.tail = tail.next;
size++;
}
}
#Override
public T dequeue() {
if(isEmpty())throw new NoSuchElementException("This queue is empty");
T returnObj = this.head.data; //saving the data of the first element(head)
//If there are at least 2 nodes, else.
if(head != tail){
this.head = head.getNext();
size--;
}
else{
this.head = null;
this.tail = head;
this.size = 0;
}
return returnObj;
}
#Override
public T first() {
return this.head.data;
}
#Override
public T last() {
return this.tail.data;
}
/* I absolutely can not get past this NullPointerException that is given every time
* I try to use the iterator. It seems that current.next is always null(doesn't point to head properly?).
* HOWEVER, if you change "curr" for "head", it works. */
#Override
public Iterator<T> iterator() {
return new GenericIterator();
}
private class GenericIterator implements Iterator<T>{
public myNode<T> curr = head;
public boolean hasNext() {
return (head != null && head.next != null);
}
public T next() {
T tmp = head.data; //saving current in a temporary node because we are changing the value of current in the next line
if(hasNext()){
head = head.next;
}
return tmp;
}
}
private class myNode<T> { //parameter type T hiding type T
public T data; //The generic data the nodes contain
public myNode<T> next; //Next node
//Node constructor
public myNode(T nData) {
this.data = nData;
this.next = null;
}
public myNode<T> getNext(){
return this.next;
}
}
}
Here is the part that is giving me trouble:
/* I absolutely can not get past this NullPointerException that is given every time
* I try to use the iterator. It seems that current.next is always null(doesn't point to head properly?).
* HOWEVER, if you change "curr" for "head", it works. */
#Override
public Iterator<T> iterator() {
return new GenericIterator();
}
private class GenericIterator implements Iterator<T>{
public myNode<T> curr = head; //doesn't work with getter either.
//public myNode<T> curr = getterHead();
public boolean hasNext() {
return (curr != null && curr.next != null);
}
public T next() {
T tmp = curr.data; //NPE HERE!
if(hasNext()){
curr = curr.next;
}
return tmp;
}
}
What I have tried is getters/setters and triple-checking every other method(they work). What seems to be the problem is that when I assign curr = head, it seems that the properties from myNode do not come with.
While head.next works fine, curr.next == null, even curr.data == null while head.data works.
I've tried with public properties and printing LinkedQueue.head.next etc, it works fine.
Stacktrace:
Exception in thread "main" java.lang.NullPointerException
at dk222gw_lab4.Queue.LinkedQueue$GenericIterator.next(LinkedQueue.java:101)
at dk222gw_lab4.Queue.LinkedQueueMain.main(LinkedQueueMain.java:17)
Where line 101 & 17 are:
T tmp = curr.data; //node property .data & .next are null.
System.out.println(it.next()); //LinkedQueueMain.java(not included in post), both it.next() and it.hasNext() produce this NPE.
I am attempting to create a custom Iterator on a LinkedList class I have made. I have been asked to alter the add function so that it adds objects Term in order from smallest to largest. (Term is a simple class taking the form Term(int power))
I cannot figure out how to create a loop in addTerm() in order to keep searching the next element to see if it is larger than the current power in Term. Can anyone help?
import java.util.Iterator;
public class customImpl implements custom{
private static class Node {
Term data;
Node next;
}
private Node head;
private class TermIterator implements Iterator<Term> {
private Node current;
private TermIterator(Node start) {
current = start;
}
#Override
public boolean hasNext() {
return current != null;
}
#Override
public Term next() {
Term result = current.data;
current = current.next;
return result;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported");
}
}
/**
* Add a term to the expression
*
* #param term the term to be added.
*/
#Override
public void addTerm(Term term) {
TermIterator iterator = new TermIterator(head);
Node newNode = new Node();
while(iterator.hasNext()) {
if(term.getPower() > iterator.next().getPower()) {
newNode.next = head;
}
else newNode.data = term;
}
newNode.data = term;
newNode.next = head;
head = newNode;
}
/**
* Returns an iterator over elements of type {#code T}.
*
* #return an Iterator.
*/
#Override
public Iterator<Term> iterator() {
return new TermIterator(head);
}
}
You cannot easily use your iterator as it goes through values instead of nodes:
#Override
public void addTerm(Term term) {
Node newNode = new Node();
newNode.term = term;
Node smaller = null; //smaller holds last element smaller than new term
Node current = head;
while(current != null) {
if(term.getPower() > current.term.getPower()) {
smaller = current;
break;
}
current = current.next;
}
if (smaller == null) {
newNode.next = head;
head = newNode;
} else {
newNode.next = smaller.next;
smaller.next = newNode;
}
}
If you want to use iterator, than you should define the 'Node' iterator (and use it in your addTerm method), and re-use it to define the 'Term' iteraotr:
class NodeIterator implements Iterator<Node> {
Node next;
NodeIterator() {
next = head;
}
#Override
public boolean hasNext() {
return (next != null);
}
#Override
public Node next() {
if (next == null) throw new NoSuchElementException();
Node res = next;
next = next.next;
return res;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class TermIterator implements Iterator<Term> {
final NodeIterator iter = new NodeIterator();
#Override
public boolean hasNext() {
return iter.hasNext();
}
#Override
public Term next() {
return iter.next().term;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
I have created a linked list in java, the issue is with
public void add(T data)
when I try to add some thing at the end of the list, "null" is getting added to the end of the list. I think there is some problem with my iterator which is not able to find the last node.
Plz help.
public class LinkedList<T> implements Iterable<T> {
private Node<T> head;
/**
* Default constructor
*
* #param head
*/
public LinkedList() {
super();
this.head = new Node<T>(null);
}
/**
* Inserts a new node at the beginning of this list.
*/
public void addFirst(T data) {
Node<T> newNode = new Node<T>(data, head);
head = newNode;
}
public void add(T data) {
Node<T> tempNpde = head;
while (tempNpde.next != null) {
tempNpde = tempNpde.next;
}
tempNpde.next = new Node<T>(data, null);
}
/**
*
* #param head
* #return
*/
public T getNode() {
return head.data;
}
#Override
public Iterator<T> iterator() {
return new ListIterator<T>();
}
public class ListIterator<T> implements Iterator<T> {
private Node<T> currentNode;
/**
* #param currentNode
*/
public ListIterator() {
super();
this.currentNode = (Node<T>) head;
}
#Override
public boolean hasNext() {
if (currentNode != null && currentNode.next != null)
return true;
else
return false;
}
#Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
T node = currentNode.data;
currentNode = currentNode.next;
return node;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
// Same as using struct in C
private static class Node<T> {
private T data;
private Node<T> next;
/**
* #param data
* #param next
*/
public Node(T data, Node<T> next) {
super();
this.data = data;
this.next = next;
}
/**
* #param next
*/
public Node(Node<T> next) {
super();
this.data = null;
this.next = next;
}
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.addFirst("aaaa");
list.addFirst("bbbb");
list.add("dddd");
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
As was already said, the biggest issue was that your next() wasn't doing what you thought it was... try this:
public class LinkedList<T> implements Iterable<T> {
private Node<T> head;
/**
* Default constructor
*
* #param head
*/
public LinkedList() {
super();
this.head = null;
}
/**
* Inserts a new node at the beginning of this list.
*/
public void addFirst(T data) {
Node<T> newNode = new Node<T>(data, head);
head = newNode;
}
public void add(T data) {
if ( head == null )
{
head = new Node<T>(data, null);
return;
}
Node<T> tempNode = head;
while (tempNode.next != null) {
tempNode = tempNode.next;
}
tempNode.next = new Node<T>(data, null);
}
/**
* #param head
* #return
*/
public T getNode() {
return head.data;
}
#Override
public Iterator<T> iterator() {
return new ListIterator<T>();
}
public class ListIterator<T> implements Iterator<T> {
private Node<T> currentNode;
private Node<T> previous;
/**
* #param currentNode
*/
public ListIterator() {
super();
this.currentNode = (Node<T>) head;
this.previous = null;
}
#Override
public boolean hasNext() {
if (currentNode != null && currentNode.next != null)
return true;
else
return false;
}
#Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
if ( previous == null )
{
previous = currentNode;
return previous.data;
}
T node = currentNode.data;
currentNode = currentNode.next;
return currentNode.data;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
// Same as using struct in C
private static class Node<T> {
private T data;
private Node<T> next;
/**
* #param data
* #param next
*/
public Node(T data, Node<T> next) {
super();
this.data = data;
this.next = next;
}
/**
* #param next
*/
public Node(Node<T> next) {
super();
this.data = null;
this.next = next;
}
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("aaaa");
list.add("bbbb");
list.addFirst("cccc");
list.add("dddd");
list.add("eeee");
list.add("ffff");
for ( String s : list ) // same thing as using an iterator
System.out.println(s);
}
}
This is the entirety of the class. This should fix the functionality for you, but if you spot any unsatisfactory changes (e.g. changing the head to initially be null instead of a node with null data), let me know...
A much simpler solution is to just modify your ListIterator#hasNext() implementation as
#Override
public boolean hasNext() {
if (currentNode != null)
return true;
else
return false;
}
The reason your last element isn't getting covered by your ListIterator is that it will always return false for currentNode.next != null because it's at the end.
Removing this condition doesn't break your iterator implementation. With the above changes, when your ListIterator is at the last element, hasNext() returns true now. The subsequent next() call returns the currentNode.data and points the ListIterator to null which then breaks the iteration loop as required.
So basically, your ListIterator#next() implementation was just fine.
Why not simply keep track of Head and Tail as two separate fields and, when you need to add a new node, set Tail.next to your new node and then set Tail to the new node? Iterating through the entire list every time you want to add something is terribly inefficient.
Also, to directly answer your question, your iterator is broken. Take a look at what your next() method is doing. Is it, in fact, returning the next Node?
My problem is in the add method. I think I know what I want it to do but I can't figure out what type of loop I should use to look through the list. As you can see I started to make a if else loop but I couldn't figure out what I should use as the counter. I'm pretty sure I have the right logic in dealing with the add but I feel like I'm not quite there yet. I was thinking of using compareTo in some fashion.
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node topNode;
private class Node
{
private E data;
private Node nextNode;
public Node(E data)
{
this.data = data;
nextNode = null;
}
}
public OrderedLinkedList()
{
topNode = null;
}
public boolean empty()
{
if(topNode == null)
return true;
return false;
}
public String toString()
{
String myString = "";
Node nextNode = topNode;
while(nextNode != null)
{
myString = topNode + " -> " + nextNode;
nextNode = topNode.nextNode;
}
return myString;
}
public void add(E data)
{
Node myNode = new Node(data);
Node priorNode = topNode;
Node currentNode = topNode;
if(___)
{
priorNode = currentNode;
currentNode = currentNode.nextNode;
}
else
{
priorNode.nextNode = myNode;
myNode.nextNode = currentNode;
}
}
}
Since you don't typically know the length of a linked list until you've walked down it, the usual thing would be to use a while loop (as you've done in your toString() method)
Perhaps using a doubly linked list would be more beneficial. Consider the following alterations to your class:
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node head;
private Node tail;
private class Node
{
private E data;
private Node nextNode;
private Node prevNode;
public Node(E data)
{
this.data = data;
nextNode = null;
prevNode = null;
}
public void setNext(Node node)
{
this.nextNode = node;
}
public Node getNext()
{
return this.nextNode;
}
public void setPrev(Node node)
{
this.prevNode = node;
}
public Node getPrev()
{
return this.prevNode;
}
public E getData()
{
return this.data;
}
public int compareTo(Node that) {
if(this.getData() < that.getData())
{
return -1;
}
else if(this.getData() == that.getData()
{
return 0;
}
else
{
return 1;
}
}
}
public OrderedLinkedList()
{
head = new Node(null);
tail = new Node(null);
head.setNext(tail);
tail.setPrev(head);
}
public boolean empty()
{
if(head.getNext() == tail)
{
return true;
}
return false;
}
public void add(E data) {
Node tmp = new Node(data);
if(this.empty()) {
this.addNodeAfterNode(tmp, head);
} else {
Node that = head.getNext();
// this while loop iterates over the list until finding the correct
// spot to add the new node. The correct spot is considered to be
// when tmp's data is >= that's data, or the next node after 'that'
// is tail. In which case the node is added to the end of the list
while((tmp.compareTo(that) == -1) && (that.getNext() != tail)) {
that = that.getNext();
}
this.addNodeAfterNode(tmp, that);
}
}
private void addNodeAfterNode(Node addNode, Node afterNode)
{
addNode.setNext(afterNode.getNext());
afterNode.getNext().setPrev(addNode);
afterNode.setNext(addNode);
addNode.setPrev(afterNode);
}
}
Does anything need to go into the main method or the constructor method for a linkedlist class like this? Also, I think my program is working fine, but I think I might be using more lines of code that I have to for my purposes, which are just to sort a list of strings. Are there any redundancies or logical errors in the add/remove methods and the OrderedListNode class below? Should I make all variables private in the LinkedList class?
package orderedlinkedlist;
/**
* Class OrderedLinkedList.
*
* This class functions as a linked list, but ensures items are stored in ascending order.
*/
public class OrderedLinkedList
{
public static void main(String args[]){
}
/** return value for unsuccessful searches */
private static final OrderedLinkedList NOT_FOUND = null;
/** current number of items in list */
public int theSize; //was private
/** reference to list header node */
private OrderedListNode head;
/** reference to list tail node */
private OrderedListNode tail;
/** current number of modifications to list */
public int modCount;
/**
* Create an instance of OrderedLinkedList.
*
*/
public OrderedLinkedList()
{
clear();
}
public boolean add(String obj) //is it ok that you changed from comparable to string?
{
OrderedListNode newNode = new OrderedListNode(obj); // placed at end of list
if(this.isEmpty()){ //
head.setNextNode(newNode);
newNode.setNextNode(tail);
newNode.setPreviousNode(head);
tail.setPreviousNode(newNode);
} else if(obj == null) {
head.getNext().setPreviousNode(newNode);
newNode.setNextNode(head.getNext());
head.setNextNode(newNode);
newNode.setPreviousNode(head);
} else {
int compareToNode;
for(OrderedListNode node = head.getNext(); node != tail; node = node.getNext()){
compareToNode = obj.compareToIgnoreCase((node.getData() == null)? "": node.getData().toString());
if(compareToNode < 0){
OrderedListNode nodeBefore = node.getPrevious();
OrderedListNode nodeAfter = node;
nodeBefore.setNextNode(newNode);
nodeAfter.setPreviousNode(newNode);
newNode.setNextNode(nodeAfter);
newNode.setPreviousNode(nodeBefore);
break;
} else if(node.getNext() == tail) {
OrderedListNode nodeBefore = node;
OrderedListNode nodeAfter = node.getNext();
nodeBefore.setNextNode(newNode);
nodeAfter.setPreviousNode(newNode);
newNode.setNextNode(nodeAfter);
newNode.setPreviousNode(nodeBefore);
break;
}
}
}
theSize++;
modCount++;
return true;
}
public boolean remove(String obj) //removes first string obj instance it finds?
{
// TODO: implement this method (7 points)
for(OrderedListNode node = head.getNext();node != tail; node=node.getNext()){
if(node.getData() == obj){
OrderedListNode nodeBefore = node.getPrevious();
OrderedListNode nodeAfter = node.getNext();
nodeBefore.setNextNode(nodeAfter);
nodeAfter.setPreviousNode(nodeBefore);
node = null;
theSize--;
modCount++;
return true;
}
}
return false;
}
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++;
}
public boolean isEmpty()
{
return theSize == 0;
}
public int size()
{
return theSize;
}
public String toString()
{
String s = "";
OrderedListNode currentNode = head.next;
while (currentNode != tail)
{
s += currentNode.getData(); //getData was "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
*/
public class OrderedListNode {
private Comparable data;
private OrderedListNode next;
private OrderedListNode previous;
public OrderedListNode() {
this.data = null;
this.next = null;
}
public OrderedListNode(Comparable inputData) { //check this
this.data = inputData;
}
public OrderedListNode(Comparable inputData, OrderedListNode previous, OrderedListNode next) {
this.data = inputData;
this.previous = previous;
this.next = next;
}
public Comparable getData() {
return data;
}
public void setData(Comparable data) {
this.data = data;
}
public OrderedListNode getNext() {
return next;
}
public void setNextNode(OrderedListNode next) {
this.next = next;
}
public OrderedListNode setPreviousNode(OrderedListNode previous) {
this.previous = previous;
return previous;
}
private OrderedListNode getPrevious() {
return getNodeAt(indexOf(this)>=0 ? indexOf(this): theSize);//0
}
private OrderedListNode getNodeAt(int givenPosition){
OrderedListNode currentNode = head;
for(int counter = 0; counter < givenPosition; counter++){
currentNode = currentNode.getNext();
}
return currentNode;
}
private int indexOf(OrderedListNode givenNode){
int count = 0;
for(OrderedListNode node = head.getNext();node != tail; node=node.getNext(), count++){
if(givenNode == node)
return count;
}
return -1;
}
}
}
package orderedlinkedlist;
public class testClass {
public static void main(String args[]){
OrderedLinkedList list = new OrderedLinkedList();
list.add("tesla");
list.add(null);
list.add("walnuts"); //move these to main method
list.add("chocolate");
list.add("swordfish");
list.add(null);
list.remove("chocolate");
list.add("pizza");
list.add("apple");
list.add(null);
list.add("1");
list.add("zebra");
System.out.println(list.toString());
System.out.println("Items in this list: " + list.theSize);
System.out.println("Modifications made: " + list.modCount);
}
}
A general purpose utility class designed should not have a main method, since someone else is expected to use this class.
An example would be the test class you have that uses your code and has a main method.
As far as you code goes,
I don't think it is thread safe. That might not be a problem, but in general it is recommended that you document that the code is not thread safe
Does you code compile? The statement should have given a compilation issue since the + operator is not overloaded for Comparable
s += currentNode.getData(); //getData was "theItem.toString()"
You might want to avoid the use of + operator in your toString method and instead go for the more efficient StringBuilder
theSize and modCount should not be public.
Following Java convention, you should add a constructor taking another Collection as an arg, e.g.
public OrderedLinkedList(Collection in)
that copies from that Collection.