I implemented doubly linked lists using nodes in Java. My code for the Node and linked list classes are below. Any suggestions for improving the design and/or running times of the operations?
public class Node implements Comparable<Node>{
Node next;
Node previous;
Object element;
int index;
public Node(Object element){
this.element = element;
this.next = null;
this.previous = null;
}
public Node(Object element, Node next, Node previous){
this.element = element;
this.next = next;
this.previous = previous;
}
public Node(Object element, Node next, Node previous, int index){
this.element = element;
this.next = next;
this.previous = previous;
this.index = index;
}
//Getter Method
public Node get_next(){
return this.next;
}
//For comparable class
public int compareTo(Node x){
if (this.element.equals(x.element)){
return 0;
}
else
return 1;
}
public boolean compare_index(int index){
if (this.index == index){
return true;
}
else
return false;
}
}
public class Mylinkedlists{
Node first_node;
Node last_node;
int size = 0;
//Constructors
public Mylinkedlists(Object element){
Node temp = new Node(element, last_node,first_node,0);
first_node = new Node (null,temp,null);
last_node = new Node(null,null,temp);
size+=1;
}
public Mylinkedlists(){
first_node = new Node (null,last_node,null);
last_node = new Node(null,null,first_node);
}
//Returns size of Node
public int size(){
return size;
}
//Adds element to end of linked list
public void add(Object element){
Node to_add = new Node(element);
Node temp = last_node.previous;
size+=1;
//Pointer changes
last_node.previous.next = to_add;
last_node.previous = to_add;
to_add.previous = temp;
to_add.next = last_node;
to_add.index = size-1;
}
//Inserts Element after node
public void insert(Object add_after, Object element_to_add) throws NotFoundException{
Node current = first_node.next;
Node insert_after = new Node(add_after);
Node to_add = new Node(element_to_add);
//find the node
while (current.compareTo(insert_after) != 0){
current = current.next;
}
//Inserts element after node
if (current.compareTo(insert_after) == 0){
Node temp = current.next;
current.next.previous = to_add;
to_add.next = temp;
current.next = to_add;
to_add.previous = current;
size+=1;
}
else
throw new NotFoundException("Element not in list");
}
//Removes element from linked list
public void remove(Object element) throws NotFoundException{
boolean stop = false;
Node search_for = new Node(element);
Node current = first_node.next;
for (int i = 0; i < size && !stop; i ++){
//Compares nodes
if (current.compareTo(search_for) == 1){
current.next.previous = current.previous;
current.previous.next = current.next;
current.next = null;
current.previous = null;
size-=1;
stop = true;
}
else
current = current.next;
}
//If element not in list
if (stop == false && current.next == null)
throw new NotFoundException("Element not in list");
}
//Removes element from end of linked list
public void remove_From_End(){
last_node.previous.next = null;
Node temp = last_node.previous.previous;
last_node.previous.previous = null;
last_node.previous = temp;
last_node.previous.next = last_node;
size -= 1;
}
//Returns true if list contains element, else false
public boolean contains(Object element){
boolean contains = false;
Node current = first_node.next;
Node with_element = new Node(element);
while (current.next != null){
if (current.compareTo(with_element) == 0)
return true;
else
current = current.next;
}
return contains;
}
public Object get(int index) throws NotFoundException{
if (index < 0 || index > (size-1))
throw new NotFoundException("Index out of range");
Node current = first_node;
for (int i = 0; i <= index; i++){
current = current.next;
}
return current.element;
}
public String toString(){
String temp = "";
Node temp2 = first_node;
for (int i = 0 ; i < size; i++){
temp2 = temp2.next;
temp += String.valueOf(temp2.element) + " ";
}
return temp;
}
}
For example, I access the elements of the Node class directly using dot(.) notation. Are getter and setter methods the only alternative? Moreover, is there any other implementation of the get method that would take less than O(n) time?
It is impossible for access to a linked list to take less than O(n). You will need to traverse through the array to access indivividual elements. There are faster ways to access individual elements, but that would require changing your data structure. The easiest data structure that I can think of would be an array. But then your insert and remove would be O(n).
So, in choosing your data structure, the question becomes what will you be doing more of insert and remove, or get?
Related
I tried to implement a linked list in java using the code below:
class Linkedlist<T>{
private node head, tail;
public Linkedlist(){
head = new node(null);
tail = head;
}
public boolean insert(T value){
if(head.getValue() == null){
this.head.setValue(value);
head.setNext(null);
return true;
}
node insertNode = new node(value);
tail.setNext(insertNode);
tail = insertNode;
return true;
}
public boolean insert(T value, int index) {
if ( sizeOfList() == index + 1 ) return false;
node temp = this.head.getNext();
node prvtmp = this.head;
for (int i = 0; i <= index; i++) {
temp = temp.getNext();
prvtmp = temp;
System.out.println("for loop");
}
node insertNode = new node(value);
System.out.println("node created");
prvtmp.setNext(insertNode);
insertNode.setNext(temp);
System.out.println("temps");
return true;
}
public int sizeOfList(){
int size = 0;
node temp = this.head;
while(temp.getNext() != null){
temp = temp.getNext();
size++;
}
return size;
}
public String[] rtrnList(){
node temp = this.head;
int listSize = sizeOfList();
String[] resualt = new String[listSize + 1];
for (int i = 0;i <= listSize;i++){
resualt[i] = String.valueOf(temp.getValue());
temp = temp.getNext();
}
return resualt;
}
}
Class node:
public class node<T> {
private T value;
private node next;
public node(T value){
this.value = value;
this.next = null;
}
public void setValue(T value) {
this.value = value;
}
public void setNext(node next) {
this.next = next;
}
public T getValue() {
return value;
}
public node getNext() {
return next;
}
}
When I try to run the insert method with one argument it works fine, but when I run it with two arguments:
import java.util.Arrays;
public class main {
public static void main(String[] args){
Linkedlist list = new Linkedlist();
list.insert(2);
list.insert(2);
list.insert(2);
list.insert(2);
list.insert(2);
list.insert(2);
list.insert(11, 3);
System.out.println(Arrays.toString(list.rtrnList()));
System.out.println("finished");
}
}
The program doesn't reach the line that prints finished, but if we delete the line: list.insert(11, 3);
Then the program works just fine.
output:
for loop
for loop
for loop
for loop
node created
finish insert
The problems is inside the for loop of your insert(T value, int index) method when you are updating the value of prvtm and temp. In your code you are first setting the value of temp to temp.getnext() and as the temp is already changed setting prvtmp to temp creating a loop which is why when you are trying to print the list it's getting into an infinite loop while calculating the size of the list.
Just put the prvtmp = temp line before temp = temp.getNext() like following code snippet. This will solve the problem.
public boolean insert(T value, int index) { // 2 2 2 2 2 2
if ( sizeOfList() == index + 1 ) return false;
node temp = this.head.getNext();
node prvtmp = this.head;
for (int i = 0; i <= index; i++) {
prvtmp = temp;
temp = temp.getNext();
System.out.println("for loop");
}
node insertNode = new node(value);
System.out.println("node created");
prvtmp.setNext(insertNode);
insertNode.setNext(temp);
System.out.println("temps");
return true;
}
Also if you are trying to insert in the given index update the condition of the for loop from:
i <= index to i < index - 1
Happy coding!
while inserting there is a cyclic refrence made , you can use this code for above purpose
public boolean insert(T value, int index) {
if(index > sizeOfList())
{
return false;
}
else if(index == sizeOfList())
{
if(insert(value))
return true;
else
return false;
}
else
{
node previous = this.head;
for (int i = 1; i <= index; i++) {
if(i==index-1)
{
node newnode = new node(value);
newnode.setNext(previous.getNext());
previous.setNext(newnode);
break;
}
previous = previous.getNext();
}
}
return true;
}
Output
[2, 2, 11, 2, 2, 2, 2]
This is my first question here.
I am trying to manually sort a linked list of integers in java and I can not figure out what is wrong with my code. Any suggestions? I don't get any error, however I still have my output unordered. I tried a few different ways, but nothing worked. I appreciate if anyone can help me with that.
public class Node {
int data;
Node nextNode;
public Node(int data) {
this.data = data;
this.nextNode = null;
}
public int getData() {
return this.data;
}
} // Node class
public class DataLinkedList implements DataInterface {
private Node head;
private int size;
public DataLinkedList(){
this.head = null;
this.size = 0;
}
public void add(int data) {
Node node = new Node(data);
if (head == null) {
head = node;
} else {
Node currentNode = head;
while(currentNode.nextNode != null) {
currentNode = currentNode.nextNode;
}
currentNode.nextNode = node;
}
size++;
}
public void sort() {
if (size > 1) {
for (int i = 0; i < size; i++ ) {
Node currentNode = head;
Node next = head.nextNode;
for (int j = 0; j < size - 1; j++) {
if (currentNode.data > next.data) {
Node temp = currentNode;
currentNode = next;
next = temp;
}
currentNode = next;
next = next.nextNode;
}
}
}
}
public int listSize() {
return size;
}
public void printData() {
Node currentNode = head;
while(currentNode != null) {
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.nextNode;
}
}
public boolean isEmpty() {
return size == 0;
}
} // DataInterface class
public class DataApp {
public static void main (String[]args) {
DataLinkedList dll = new DataLinkedList();
dll.add(8);
dll.add(7);
dll.add(6);
dll.add(4);
dll.add(3);
dll.add(1);
dll.sort();
dll.printData();
System.out.println(dll.listSize());
}
} // DataApp class
The problem, as expected, comes in method sort():
public void sort() {
if (size > 1) {
for (int i = 0; i < size; i++ ) {
Node currentNode = head;
Node next = head.nextNode;
for (int j = 0; j < size - 1; j++) {
if (currentNode.data > next.data) {
Node temp = currentNode;
currentNode = next;
next = temp;
}
currentNode = next;
next = next.nextNode;
}
}
}
}
A minor problem is just do always execute the bubble sort n*n times. It is actually better check whether there was a change between any pair in the list. If it was, then there is the need to run again all over the list; if not, there isn't. Think of the marginal case in which a list of 100 elements is already sorted when sort() is called. This means that nodes in the list would be run over for 10000 times, even when there is actually nothing to do!
The main problem, though, is that you are exchanging pointers to the nodes in your list.
if (currentNode.data > next.data) {
Node temp = currentNode;
currentNode = next;
next = temp;
}
If you translate currentNode by v[i] and next by v[i - 1], as if you were sorting an array, that would do. However, you are just changing pointers that you use to run over the list, without effect in the list itself. The best solution (well, provided you are going to use BubbleSort, which is always the worst solution) would be to exchange the data inside the nodes.
if (currentNode.data > next.data) {
int temp = currentNode.data;
currentNode.data = next.data;
next.data = temp;
}
However, for a matter of illustration of the concept, I'm going to propose changing the links among nodes. These pointers are the ones which actually mark the sorting in the list. I'm talking about the nextNode attribute in the Node class.
Enough chat, here it is:
public void sort() {
if (size > 1) {
boolean wasChanged;
do {
Node current = head;
Node previous = null;
Node next = head.nextNode;
wasChanged = false;
while ( next != null ) {
if (current.data > next.data) {
/*
// This is just a literal translation
// of bubble sort in an array
Node temp = currentNode;
currentNode = next;
next = temp;*/
wasChanged = true;
if ( previous != null ) {
Node sig = next.nextNode;
previous.nextNode = next;
next.nextNode = current;
current.nextNode = sig;
} else {
Node sig = next.nextNode;
head = next;
next.nextNode = current;
current.nextNode = sig;
}
previous = next;
next = current.nextNode;
} else {
previous = current;
current = next;
next = next.nextNode;
}
}
} while( wasChanged );
}
}
The explanation for a "double" code managing the node exchange is that, since you have to change the links among nodes, and this is just a single linked list, then you have to keep track of the previous node (you don't have a header node, either), which the first time is head.
if ( previous != null ) {
Node sig = next.nextNode;
previous.nextNode = next;
next.nextNode = current;
current.nextNode = sig;
} else {
Node sig = next.nextNode;
head = next;
next.nextNode = current;
current.nextNode = sig;
}
You can find the code in IdeOne, here: http://ideone.com/HW5zw7
Hope this helps.
You need to swap the data not just the nodes.
public void sort() {
if (size > 1) {
for (int i = 0; i < size; i++ ) {
Node currentNode = head;
Node next = head.nextNode;
for (int j = 0; j < size - 1; j++) {
if (currentNode.data > next.data) {
int temp = currentNode.data;
currentNode.data = next.data;
next.data = temp;
}
currentNode = next;
next = next.nextNode;
}
}
}
}
you can write this methode like this:
class Node {
int data = 0;
Node next;
public Node(int data) {
this.data = data;
}
}
public void sort() {
Node current = head;
while (current != null) {
Node second = current.next;
while (second != null) {
if (current.data > second.data) {
int tmp = current.data;
current.data = second.data;
second.data = tmp;
}
second = second.next;
}
current = current.next;
}
}
I made a singly linked list from scratch in java. The code is as follows:
public class SingleLinkedList<Item>
{
private Node head;
private int size;
private class Node
{
Item data;
Node next;
public Node(Item data)
{
this.data = data;
this.next = null;
}
public Node(Item data, Node next)
{
this.data = data;
this.next = next;
}
//Getters and setters
public Item getData()
{
return data;
}
public void setData(Item data)
{
this.data = data;
}
public Node getNext()
{
return next;
}
public void setNext(Node next)
{
this.next = next;
}
}
public SingleLinkedList()
{
head = new Node(null);
size = 0;
}
public void add(Item data)
{
Node temp = new Node(data);
Node current = head;
while(current.getNext() != null)
{
current = current.getNext();
}
current.setNext(temp);
size++;
}
public void add(Item data, int index)
{
Node temp = new Node(data);
Node current = head;
for(int i=0; i<index && current.getNext() != null; i++)
{
current = current.getNext();
}
temp.setNext(current.getNext());
current.setNext(temp);
size++;
}
public Item get(int index)
{
if(index <= 0)
{
return null;
}
Node current = head;
for(int i=1; i<index; i++)
{
if(current.getNext() == null)
{
return null;
}
current = current.getNext();
}
return current.getData();
}
public boolean remove(int index)
{
if(index < 1 || index > size())
{
return false;
}
Node current = head;
for(int i=1; i<index; i++)
{
if(current.getNext() == null)
{
return false;
}
current = current.getNext();
}
current.setNext(current.getNext().getNext());
size--;
return true;
}
public String toString()
{
Node current = head.getNext();
String output = "";
while(current != null)
{
output+=current.getData().toString()+" ";
current = current.getNext();
}
return output;
}
public int size()
{
return size;
}
public void reverse()
{
Node current = head;
Node prevNode = null;
Node nextNode;
while(current!=null)
{
nextNode = current.getNext();
current.setNext(prevNode);
prevNode = current;
current = nextNode;
System.out.println(prevNode.getData());
}
head = prevNode;
}
}
As you can see, I added the reverse function in the class only.
But when I tried actually using the class it gave NullPointerException after I tried to reverse it.
To check the functionality I used another class called TEST. The code is as follows:
public class TEST
{
public static void main(String[] args)
{
SingleLinkedList<Integer> list = new SingleLinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list.toString());
list.reverse();
System.out.println(list.toString());
}
}
The output is as follows:
1 2 3 4 5
null
1
2
3
4
5
Exception in thread "main" java.lang.NullPointerException
at SingleLinkedList.toString(SingleLinkedList.java:129)
at TEST.main(TEST.java:20)
I tried to print the value of prevNode to check whether its not taking values...but it is.
What to do?
Actually, your reverse method looks fine.
The problem is your toString() method.
When you create a new list, you create an initial element whose data is null.
Your toString method skips that first element, so it works fine as long as you don't reverse the list.
But when you reverse the list, that null element becomes the last element, and when you call output+=current.getData().toString()+" "; for that last element when current.getData() is null, you get NullPointerException.
You have several options :
Your reverse method can keep the initial null element first (i.e. reverse the rest of the list, but keep the head the same). This way toString can remain unchanged.
Eliminate the initial null element. Then your toString method doesn't have to skip anything.
Keeping the null element first :
public void reverse()
{
Node current = head.getNext();
Node prevNode = null;
Node nextNode;
while(current!=null)
{
nextNode = current.getNext();
current.setNext(prevNode);
prevNode = current;
current = nextNode;
System.out.println(prevNode.getData());
}
head.setNext(prevNode);
}
The problem is in your SingleLinkedList.java toString() method
Try below it is working fine
public String toString() {
Node current = head;
String output = "";
while (current != null) {
// output += current.getData().toString() + " ";
output += String.valueOf(current.getData()) + " ";
current = current.getNext();
}
return output;
}
while(current!=null)
This is your problem. When you hit the last node the 'next' node you get is actually null.
Try changing it to
while(current!=null&¤t.getNext()!=null)
EDIT: Actually not sure that solution will work. Try putting a conditional at the end of your loop that says:
if(current.getNext()==null)
break;
EDIT (again :/):
ok sorry I wasn't thinking straight.
change that final if statement to:
if(current.getNext()==null){
current.setNext(prevNode);
break;
}
The actual nullpointer is in the toString. Here's what you do:
Change the while conditional to
while(current != null&¤t.getData()!=null)
Because otherwise if current points to null then you get an exception.
That was exhausting.
This is a homework question. I have a Double Linked Node class, Circular Double Linked List class which implements Iterable, and a Iterator class that implements Iterator. I understand the concept of an iterator where an implicit cursor sits between two nodes and on a call to next() it returns the node it just jumped over. I created a test class with a new list object. I then created an iterator and called next, I received the correct No Such Element exception but when I added some nodes to the list I received a Null Pointer Exception instead of it returning the last returned node. How can I correct this?
My Node class:
public class DoubleLinkedNode<E>{
private E data;
private DoubleLinkedNode<E> next;
private DoubleLinkedNode<E> prev;
public DoubleLinkedNode(E data, DoubleLinkedNode<E> next, DoubleLinkedNode<E> prev){
this.data = data;
this.next = next;
this.prev = prev;
}
/**
* Used to construct a node that points to null for its prev and next.
* #param data Data is a generic variable to be stored in the node.
*/
public DoubleLinkedNode(E data){
this(data, null, null);
}
//getters
public E getData(){
return data;
}
public DoubleLinkedNode<E> getNext(){
return next;
}
public DoubleLinkedNode<E> getPrev(){
return prev;
}
//setters
public void setData(E data){
this.data = data;
}
public void setNext(DoubleLinkedNode<E> next){
this.next = next;
}
public void setPrev(DoubleLinkedNode<E> prev){
this.prev = prev;
}
#Override public String toString(){
if(data == null){
return null;
}
else{
return data.toString();
}
}
}
The List class with the private inner Iterator class:
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;
public class CircularDoubleLinkedList<E> implements Iterable<E>{
private int size;
private DoubleLinkedNode<E> head;
public CircularDoubleLinkedList(){
this.head = null;
this.size = 0;
}
/**
* Adds an item to the end of the list.
*
* #param data The Data that is to be stored in the node.
*/
public void add(E data){
DoubleLinkedNode<E> newNode = new DoubleLinkedNode<E>(data);
if(this.head == null){
newNode.setNext(newNode);
newNode.setPrev(newNode);
this.head = newNode;
this.size++;
//if list is empty create a new node and insert
}
else{
DoubleLinkedNode<E> temp = this.head.getPrev();
this.head.getPrev().setNext(newNode);
this.head.setPrev(newNode);
newNode.setPrev(temp);
newNode.setNext(this.head);
this.size++;
}
}
/**
* Which adds an item at the specified index.
*
* #param index The index in which the new Node is added.
* #param data The data which is to be stored in the node.
*/
public void add(int index, E data){
int currIndex = 0;
DoubleLinkedNode<E> currNode = this.head;
DoubleLinkedNode<E> nextNode = this.head.getNext();
DoubleLinkedNode<E> prevNode = this.head.getPrev();
DoubleLinkedNode<E> newNode = new DoubleLinkedNode<E>(data);
if(index == 0){
prevNode.setNext(newNode);
currNode.setPrev(newNode);
newNode.setPrev(prevNode);
newNode.setNext(currNode);
this.head = newNode;
this.size++;
}
else if (index > 0){
while(currIndex != this.size){
if(currIndex != index%size){
currIndex++;
currNode = currNode.getNext();
nextNode = nextNode.getNext();
prevNode = prevNode.getNext();
}else{
newNode.setPrev(prevNode);
newNode.setNext(currNode);
prevNode.setNext(newNode);
currNode.setPrev(newNode);
currNode = newNode;
this.size++;
break;
}
}
}
else if (index < 0){
while(currIndex != -this.size){
if(currIndex != index%size){
currIndex--;
currNode = currNode.getPrev();
prevNode = prevNode.getPrev();
nextNode = nextNode.getPrev();
}else{
newNode.setNext(nextNode);
newNode.setPrev(currNode);
currNode.setNext(newNode);
nextNode.setPrev(newNode);
currNode = newNode;
this.size++;
break;
}
}
}
}
/**
* Returns the data stored at the specified index.
*
* #param index The index determines the node whose data is returned.
* #return Returns the data of the node at the index.
*/
public E get(int index){//returns the data stored at the specified index
int currIndex = 0;
DoubleLinkedNode<E> currNode = this.head;
E temp = null;
if(index == 0){//zero case
temp = currNode.getData();
}
else if(index > 0){//positive
while(currIndex != this.size){
if(currIndex != index%size){
currIndex++;
currNode = currNode.getNext();
}else{
temp = currNode.getData();
break;
}
}
}
else if(index < 0){//negative
while(currIndex != -this.size){
if(currIndex != index%size){
currIndex--;
currNode = currNode.getPrev();
}else{
temp = currNode.getData();
break;
}
}
}
return temp;
}
/**
* Which removes and returns an item from the list.
*
* #param index Removes the node at the current index.
* #return Returns the data of the removed node.
*/
public E remove(int index){//which removes and returns an item from the list
int currIndex = 0;
DoubleLinkedNode<E> currNode = this.head;
DoubleLinkedNode<E> nextNode = this.head.getNext();
DoubleLinkedNode<E> prevNode = this.head.getPrev();
E temp = null;
if(index == 0){
temp = currNode.getData();
prevNode.setNext(currNode.getNext());
nextNode.setPrev(currNode.getPrev());
this.head = nextNode;
size--;
}
else if(index > 0){//positive
while(currIndex != this.size){
if(currIndex != index%size){
currIndex++;
currNode = currNode.getNext();
nextNode = nextNode.getNext();
prevNode = prevNode.getNext();
}else{
temp = currNode.getData();
prevNode.setNext(currNode.getNext());
nextNode.setPrev(currNode.getPrev());
currNode = nextNode;
size--;
break;
}
}
}
else if(index < 0){//negative
while(currIndex != -this.size){
if(currIndex != index%size){
currIndex--;
currNode = currNode.getPrev();
prevNode = prevNode.getPrev();
nextNode = nextNode.getPrev();
}else{
temp = currNode.getData();
prevNode.setNext(currNode.getNext());
nextNode.setPrev(currNode.getPrev());
currNode = prevNode;
size--;
break;
}
}
}
return temp;
}
/**
* Returns the size.
*
* #return
*/
public int size(){
return size;
}
#Override public String toString(){
String str = "[";
int index = 0;
DoubleLinkedNode<E> curr = head;
if(size == 0){
return "There is no one here to kill.";
}else{
while (index <this.size) {
str += curr.getData();
curr = curr.getNext();
index++;
if (index<this.size) {
str += ", ";
}
}
str += "]";
}
return str;
}
#Override
public Iterator<E> iterator() {
return new CircularDoubleIterator();
}
// Iterator inner class begins
private class CircularDoubleIterator implements ListIterator<E> {
private DoubleLinkedNode<E> nextItem;//reference to next item
private int index = 0;
private DoubleLinkedNode<E> lastReturned;// the last node to be returned by prev() or next()
// reset to null after a remove() or add()
#Override
public E next() {
if(!hasNext()){
throw new NoSuchElementException("No such element.");
}
else{
nextItem = head; //edited 11Sept13
lastReturned = nextItem.getNext();
nextItem = nextItem.getNext();
head = nextItem; //edited 11Sept13
index++;
return lastReturned.getData();
}
}
#Override
public E previous() {
if(!hasPrevious()){
throw new NoSuchElementException("No such element.");
}
else{
index--;
return ;
}
}
#Override
public int nextIndex() {
return index;
}
#Override
public int previousIndex() {
return index-1;
}
#Override
public boolean hasNext() {
return size != 0;
}
#Override
public boolean hasPrevious() {
return size!= 0;
}
#Override
public void remove() {
}
#Override
public void set(E theData) {
if(lastReturned == null){
throw new IllegalStateException();
}
else{
}
}
#Override
public void add(E theData) {
if(size == 0){
}
else if(size != 0){
}
}
}
//Iterator inner class ends
}
I don't see where you assign values to private DoubleLinkedNode<E> nextItem; when you create iterator.
I cannot see the whole code. So I assume that nextItem is null or its next field is null.
I am doing some exercises on practice-it website. And there is a problem that I don't understand why I didn't pass
Write a method deleteBack that deletes the last value (the value at the back of the list) and returns the deleted value. If the list is empty, your method should throw a NoSuchElementException.
Assume that you are adding this method to the LinkedIntList class as defined below:
// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
private ListNode front; // node holding first value in list (null if empty)
private String name = "front"; // string to print for front of list
// Constructs an empty list.
public LinkedIntList() {
front = null;
}
// Constructs a list containing the given elements.
// For quick initialization via Practice-It test cases.
public LinkedIntList(int... elements) {
this("front", elements);
}
public LinkedIntList(String name, int... elements) {
this.name = name;
if (elements.length > 0) {
front = new ListNode(elements[0]);
ListNode current = front;
for (int i = 1; i < elements.length; i++) {
current.next = new ListNode(elements[i]);
current = current.next;
}
}
}
// Constructs a list containing the given front node.
// For quick initialization via Practice-It ListNode test cases.
private LinkedIntList(String name, ListNode front) {
this.name = name;
this.front = front;
}
// Appends the given value to the end of the list.
public void add(int value) {
if (front == null) {
front = new ListNode(value, front);
} else {
ListNode current = front;
while (current.next != null) {
current = current.next;
}
current.next = new ListNode(value);
}
}
// Inserts the given value at the given index in the list.
// Precondition: 0 <= index <= size
public void add(int index, int value) {
if (index == 0) {
front = new ListNode(value, front);
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = new ListNode(value, current.next);
}
}
public boolean equals(Object o) {
if (o instanceof LinkedIntList) {
LinkedIntList other = (LinkedIntList) o;
return toString().equals(other.toString()); // hackish
} else {
return false;
}
}
// Returns the integer at the given index in the list.
// Precondition: 0 <= index < size
public int get(int index) {
ListNode current = front;
for (int i = 0; i < index; i++) {
current = current.next;
}
return current.data;
}
// Removes the value at the given index from the list.
// Precondition: 0 <= index < size
public void remove(int index) {
if (index == 0) {
front = front.next;
} else {
ListNode current = front;
for (int i = 0; i < index - 1; i++) {
current = current.next;
}
current.next = current.next.next;
}
}
// Returns the number of elements in the list.
public int size() {
int count = 0;
ListNode current = front;
while (current != null) {
count++;
current = current.next;
}
return count;
}
// Returns a text representation of the list, giving
// indications as to the nodes and link structure of the list.
// Detects student bugs where the student has inserted a cycle
// into the list.
public String toFormattedString() {
ListNode.clearCycleData();
String result = this.name;
ListNode current = front;
boolean cycle = false;
while (current != null) {
result += " -> [" + current.data + "]";
if (current.cycle) {
result += " (cycle!)";
cycle = true;
break;
}
current = current.__gotoNext();
}
if (!cycle) {
result += " /";
}
return result;
}
// Returns a text representation of the list.
public String toString() {
return toFormattedString();
}
// ListNode is a class for storing a single node of a linked list. This
// node class is for a list of integer values.
// Most of the icky code is related to the task of figuring out
// if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.
public static class ListNode {
private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();
public static void clearCycleData() {
for (ListNode node : ALL_NODES) {
node.visited = false;
node.cycle = false;
}
}
public int data; // data stored in this node
public ListNode next; // link to next node in the list
public boolean visited; // has this node been seen yet?
public boolean cycle; // is there a cycle at this node?
// post: constructs a node with data 0 and null link
public ListNode() {
this(0, null);
}
// post: constructs a node with given data and null link
public ListNode(int data) {
this(data, null);
}
// post: constructs a node with given data and given link
public ListNode(int data, ListNode next) {
ALL_NODES.add(this);
this.data = data;
this.next = next;
this.visited = false;
this.cycle = false;
}
public ListNode __gotoNext() {
return __gotoNext(true);
}
public ListNode __gotoNext(boolean checkForCycle) {
if (checkForCycle) {
visited = true;
if (next != null) {
if (next.visited) {
// throw new IllegalStateException("cycle detected in list");
next.cycle = true;
}
next.visited = true;
}
}
return next;
}
}
// YOUR CODE GOES HERE
}
My work so far is this:
public int deleteBack(){
if(front==null){
throw new NoSuchElementException();
}else{
ListNode current = front;
while(current!=null){
current = current.next;
}
int i = current.data;
current = null;
return i;
}
}
Don't you want to iterate until the current.next is != null?
What you have now passes the entire list, and your last statements do nothing, since current is null already.
Think about the logic you have here
while(current!=null){
current = current.next;
}
When that loop exits, current == null, and then you try to access current's data. Does this point you in the right direction?
// This is the quick and dirty
//By Shewan
public int deleteBack(){
if(size()== 0){ throw new NoSuchElementException(); }
if(front==null){ throw new NoSuchElementException();
}else{
if(front.next == null){
int i = front.data;
front = null;
return i;
}
ListNode current = front.next;
ListNode prev= front;
while(current.next!=null){
prev = current;
current = current.next;
}
int i = current.data;
prev.next = null;
return i;
}
}