Java Linked List [duplicate] - java

This question already has an answer here:
SLinkedList and Node in Java
(1 answer)
Closed 8 years ago.
I can't seem to figure out why it's printing repeated entries and not printing in order listed. Any thoughts. here is my code for the driver.
ScoresTest
public class ScoresTest
{
public static void main(String[] args)
{
// create
SLinkedList<GameEntry> highScores = new SLinkedList<GameEntry>();
GameEntry entry;
// create entries.
Scores rank = new Scores();
entry = new GameEntry("Rick", 234);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Steve", 121);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Jeremy", 438);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Mike", 925);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Craig", 465);
highScores = rank.add(entry, highScores);
entry = new GameEntry("Juan", 777);
highScores = rank.add(entry,highScores);
System.out.println("The Original High Scores");
rank.print(highScores);
entry = new GameEntry("Tyler", 895);
highScores = rank.add(entry, highScores);
System.out.println("Scores after adding Tyler");
rank.print(highScores);
}
}
GameEntry
public class GameEntry
{
private String name; // name of the person earning this score
private int score; // the score value
// Constructor
public GameEntry(String n, int s)
{
name = n;
score = s;
}
// Get methods.
public String getName() { return name; }
public int getScore() { return score; }
// Return string representation.
public String toString()
{
return "(" + name + ", " + score + ")";
}
}// end class.
Scores
import Project1.SLinkedList.Node;
public class Scores
{
//add function
public SLinkedList<GameEntry> add(GameEntry rank, SLinkedList<GameEntry> scores)
{
Node<GameEntry> currentNode = scores.getFirst();
Node<GameEntry> nextNode = null;
Node<GameEntry> newNode = new Node<GameEntry>();
newNode.setElement(rank);
if(scores.getSize() == 0)
{
scores.addFirst(newNode);
}
else
{
while(currentNode != null)
{
nextNode = currentNode.getNext();
if(nextNode == null)
{
scores.addLast(newNode);
}
else
{
scores.addAfter(currentNode, newNode);
break;
}
currentNode = currentNode.getNext();
}
}
return scores;
}
// Print Format.
public void print(SLinkedList<GameEntry> scores)
{
Node<GameEntry> currentNode = scores.getFirst();
GameEntry currentEntry = currentNode.getElement();
System.out.printf("[");
for(int i = 0; i < scores.getSize(); i++)
{
System.out.printf(", %s", currentEntry.toString());
currentNode = currentNode.getNext();
currentEntry = currentNode.getElement();
}
System.out.println("]");
}
}
SLinkedList
public class SLinkedList<V> implements Cloneable
{
public static class Node<V>
{
// instance variables
private V element;
private Node<V> next;
// methods, constructor first
public Node ()
{
this (null, null); // call the constructor with two args
} // end no argument constructor
public Node (V element, Node<V> next)
{
this.element = element;
this.next = next;
} // end constructor with arguments
// set/get methods
public V getElement ()
{
return element;
}
public Node<V> getNext ()
{
return next;
}
public void setElement (V element)
{
this.element = element;
}
public void setNext (Node<V> next)
{
this.next = next;
}
} // End of nested node class
// instance variables.
protected Node<V> head, tail;
protected long size;
// Create empty constructor
public SLinkedList () {
head = null;
tail = null;
size = 0;
} // end constructor
// Add Fist method to add node to list.
public void addFirst (Node<V> node) {
// set the tail only if this is the very first node
if (tail == null)
tail = node;
node.setNext (head); //refer to head
head = node;
// adjust size.
size++;
} // end addFirst method.
// Add new node after current node. Checks to see if at tail also.
public void addAfter (Node<V>currentNode, Node<V>newNode) {
if (currentNode == tail)
tail = newNode;
newNode.setNext (currentNode.getNext ());
currentNode.setNext (newNode);
// adjust size.
size++;
} // end addAfter method.
// Add new node after the tail.
public void addLast (Node<V> node) {
node.setNext (null);
tail.setNext (node);
tail = node;
size++;
} // end addLast method
// Removes first node.
public Node<V> removeFirst () {
if (head == null)
System.err.println("Error: Attempt to remove from an empty list");
// save the one to return.
Node<V> temp = head;
head = head.getNext ();
temp.setNext(null);
size--;
return temp;
} // end method removeFirst
// remove the node at the end of the list.
public Node<V> removeLast () {
// // declare local variables/objects
Node<V> nodeBefore;
Node<V> nodeToRemove;
// make sure we have something to remove
if (size == 0)
System.err.println("Error: Attempt to remove fron an empty list");
// traverse through the list, getting a reference to the node before
// the trailer. Since there is no previous reference.
nodeBefore = getFirst ();
// potential error ?? See an analysis and drawing that indicates the number of iterations
// 9/21/10. size - 2 to account for the head and tail nodes. We want to refer to the one before the
// tail.
for (int count = 0; count < size - 2; count++)
nodeBefore = nodeBefore.getNext ();
// save the last node
nodeToRemove = tail;
// now, do the pointer manipulation
nodeBefore.setNext (null);
tail = nodeBefore;
size--;
return nodeToRemove;
} // end method removeLast
// Remove known node from list. Traverses through the list.
public void remove (Node<V> nodeToRemove) {
// declare local variables/references
Node<V> nodeBefore, currentNode;
// is there something to remove.
if (size == 0)
System.err.println("Error: Attempt to remove fron an empty list");
// Start at beginning of list.
currentNode = getFirst ();
if (currentNode == nodeToRemove)
removeFirst ();
currentNode = getLast ();
if (currentNode == nodeToRemove)
removeLast ();
// Check last two nodes.
if (size - 2 > 0) {
nodeBefore = getFirst ();
currentNode = getFirst ().getNext ();
for (int count = 0; count < size - 2; count++) {
if (currentNode == nodeToRemove) {
// remove current node
nodeBefore.setNext (currentNode.getNext ());
size--;
break;
} // end if node found
// references
nodeBefore = currentNode;
currentNode = currentNode.getNext ();
} // end loop to process elements
} // end if size - 2 > 0
} // end method remove
// Get methods
public Node<V> getFirst () { return head; }
public Node<V> getLast () { return tail; }
public long getSize () { return size; }
}
Here is my output.
The Original High Scores [, (Rick, 234), (Juan, 777), (Craig, 465),
(Mike, 925), (Jeremy, 438), (Steve, 121), (Steve, 121), (Steve, 121)]
Scores after adding Tyler [, (Rick, 234), (Tyler, 895), (Juan, 777),
(Craig, 465), (Mike, 925), (Jeremy, 438), (Steve, 121), (Steve, 121),
(Steve, 121)]

The while loop while(currentNode != null) only executes once, because the condition inside will break if the current item is NOT null. So it basically always adds the new item just after the first item.
The logic in the method add is very very wrong.

Related

Sorted Linked Based List Java

I'm working on an assignment for my Data Structures class. We have to create an address book using our own sorted linked based list adt. Right now the add method works, but it seems to make all the nodes point to the first node. Whenever I try to output the the list using getEntry() in a for loop, it gives me the last added entry each time. I've tried using toArray but it does the same thing. Can you see any problems?
public class GTSortedLinkedBasedList implements GTListADTInterface {
private Node firstNode;
private int numberOfEntries;
public GTSortedLinkedBasedList(){
//firstNode = new Node(null);
numberOfEntries = 0;
}
public void setNumberOfEntries(int x){
numberOfEntries = x;
}
public void add(ExtPersonType newEntry){
//firstNode = null;
Node newNode = new Node(newEntry);
Node nodeBefore = getNodeBefore(newEntry);
if (isEmpty() || (nodeBefore == null))
{
// Add at beginning
newNode.setNextNode(firstNode);
firstNode = newNode;
}
else
{
// Add after nodeBefore
Node nodeAfter = nodeBefore.getNextNode();
newNode.setNextNode(nodeAfter);
nodeBefore.setNextNode(newNode);
} // end if
numberOfEntries++;
}
private Node getNodeBefore(ExtPersonType anEntry){
Node currentNode = getFirstNode();
Node nodeBefore = null;
while ((currentNode != null) &&
(anEntry.getFirstName().compareTo(currentNode.getData().getFirstName()) > 0))
{
nodeBefore = currentNode;
currentNode = currentNode.getNextNode();
} // end while
return nodeBefore;
}
private class Node {
private ExtPersonType data;
private Node next;
public Node(ExtPersonType dataValue) {
next = null;
data = dataValue;
}
public Node(ExtPersonType dataValue, Node nextValue) {
next = nextValue;
data = dataValue;
}
public ExtPersonType getData(){
return data;
}
public void setData(ExtPersonType newData){
data = newData;
}
public Node getNextNode(){
return next;
}
public void setNextNode(Node newNode){
next = newNode;
}
}
public ExtPersonType getEntry(int givenPosition) {
if ((givenPosition >= 1) && (givenPosition <= numberOfEntries)){
assert !isEmpty();
return getNodeAt(givenPosition).getData();
}
else{
throw new IndexOutOfBoundsException("Illegal position given to getEntry operation.");
}
}
public void loadData(GTSortedLinkedBasedList contacts) throws FileNotFoundException{
//int index = 0;
ExtPersonType person = new ExtPersonType();
DateType tempDate = new DateType();
AddressType tempAddress = new AddressType();
Scanner file = new Scanner(new FileInputStream("Programming Assignment 1 Data.txt"));
while(file.hasNext()){
person.setFirstName(file.next());
person.setLastName(file.next());
tempDate.setMonth(file.nextInt());
tempDate.setDay(file.nextInt());
tempDate.setYear(file.nextInt());
person.setDOB(tempDate);
tempAddress.setStreetAddress(file.nextLine());
if(tempAddress.getStreetAddress().isEmpty()){
tempAddress.setStreetAddress(file.nextLine());
}
tempAddress.setCity(file.nextLine());
tempAddress.setState(file.nextLine());
tempAddress.setZipCode(file.nextLine());
person.setAddress(tempAddress);
person.setPhoneNumber(file.nextLine());
person.setPersonStatus(file.nextLine());
if(person.getPersonStatus().isEmpty()){
person.setPersonStatus(file.nextLine());
}
contacts.add(person);
System.out.println(contacts.getEntry(contacts.getLength()).getFirstName());
//index++;
}
}
public static void main(String[] args) throws FileNotFoundException {
AddressBook ab = new AddressBook();
ab.loadData(ab);
ExtPersonType people = new ExtPersonType();
//people = ab.toArray(people);
System.out.println(ab.getLength());
for(int cnt = 1; cnt <= ab.getLength(); cnt++){
people = ab.getEntry(cnt);
System.out.println(people.getFirstName());
}
}
EDIT: The add method is overwriting each previous object with the newly added one. It also doesn't seem to matter if I do a sorted list or just a basic list.
I'm not going to lie here, I'm not totally sure I understand your code but I think I see what's wrong. In your getNodeBefore() method's code, you set currentNode() always to firstNode(). I believe that is causing the problem. I see that you are trying to recursively move through the list to find the proper node but I don't think each recursive call is causing movement through the list. I suggest you add properties to the object that represent the forward and backward nodes.
Something like this...
private T data;
private Node nodeBefore;
private Node nodeAfter;
As you create objects, you assign the properties before and after and then all the information you need is contained in the object itself.
To move recursively through the list you would then just add a statement like currentNode = currentNode.nodeAfter.
Your getNodeBefore() method would simply return currentNode.nodeBefore and getNodeAfter() would return currentNode.nodeAfter.
You don't have code that handles the situation where the node being added will be the first node in the list, but the list is also not empty. In this case, getNodeBefore returns null, and your code overwrites the root node.
Try
if (isEmpty() && (nodeBefore == null))
{
// Add at beginning
newNode.setNextNode(firstNode);
firstNode = newNode;
}
else if(nodeBefore == null)
{
Node temp = new Node();
temp.setNextNode(first.next);
temp.setData(first.data);
newNode.setNextNode(temp);
firstNode = newNode;
}

Reversing a singly linked list in java

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&&current.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&&current.getData()!=null)
Because otherwise if current points to null then you get an exception.
That was exhausting.

Can someone tell me what i'm doing wrong? Counting and looping through LinkedList

My code is as follows:
import net.datastructures.Node;
public class SLinkedListExtended<E> extends SLinkedList<E> {
public int count(E elem) {
Node <E> currentNode = new Node <E>();
currentNode = head;
int counter = 0;
for (int i = 0; i<size; i++){
if (currentNode == null) {
return 0; //current is null
}
else if (elem.equals(currentNode.getElement())){
counter++;
currentNode = currentNode.getNext();
}
}
return counter;
}
public static void main(String[] args) {
SLinkedListExtended<String> x = new SLinkedListExtended<String>();
x.insertAtTail("abc");
x.insertAtTail("def");
x.insertAtTail("def");
x.insertAtTail("xyz");
System.out.println(x.count("def")); // should print "2"
//x.insertAtTail(null);
x.insertAtTail("def");
//x.insertAtTail(null);
System.out.println(x.count("def")); // should print "3"
//System.out.println(x.count(null)); // should print "2"
}
}
The method count is supposed to return the number of the amount of times a given element, elem is found in a list. I have written this loop but only get a return of 0 every time. A nullpointerexception is also thrown.
Edit: SLinkedList SuperClass
import net.datastructures.Node;
public class SLinkedList<E> {
protected Node<E> head; // head node of the list
protected Node<E> tail; // tail node of the list (if needed)
protected long size; // number of nodes in the list (if needed)
// default constructor that creates an empty list
public SLinkedList() {
head = null;
tail = null;
size = 0;
}
// update and search methods
public void insertAtHead(E element) {
head = new Node<E>(element, head);
size++;
if (size == 1) {
tail = head;
}
}
public void insertAtTail(E element) {
Node<E> newNode = new Node<E>(element, null);
if (head != null) {
tail.setNext(newNode);
} else {
head = newNode;
}
tail = newNode;
size++;
}
public static void main(String[] args) { // test
}
}
It seems you missed to go to the next node if non of both condition match.
public int count(E elem) {
Node <E> currentNode = new Node <E>();
currentNode = head;
int counter = 0;
for (int i = 0; i<size; i++){
if (currentNode == null) {
return 0; //current is null
}
else if (elem.equals(currentNode.getElement())){
counter++;
}
currentNode = currentNode.getNext();
}
return counter;
}
MrSmith's answer nails it, I think. I would not use size for the loop but take the fact that there is no next as bottom. Of course your count method then has to return the counter in all cases and not 0.

Deleting a node from a list

My problem: My delete node method works fine for deleting any specified node from a user created list except for the first element. How do I get this method to be able to delete the front of a list?
public void deleteNode(node spot, node front) {
node current = spot, previous = front;
while(previous.next != current) {
previous = previous.next;
}
previous.next = current.next;
}
This is the full program code.
import java.io.*;
public class LinkedList {
public int num;
public node front;
//set front to null
public void init() {
front = null;
}
//make a new node
public node makeNode(int num) {
node newNode = new node();
newNode.data = num;
newNode.next = null;
return newNode;
}
//find the end of a list
public node findTail(node front) {
node current = front;
while(current.next != null) {
current = current.next;
}
return current;
}
//find a specified node
public node findSpot(node front, int num) {
node current = front;
boolean searching = true, found = false;
while((searching)&&(!found)) {
if(current == null) {
searching = false;
}
else if(current.data == num) {
found = true;
}
else {
current = current.next;
}
}
return current;
}
//delete a specified node
public void deleteNode(node spot, node front) {
node current = spot, previous = front;
while(previous.next != current) {
previous = previous.next;
}
previous.next = current.next;
}
//add nodes to the end of a list
public void add2Back(node front, int num) {
node tail;
if (front == null) {
front = makeNode(num);
}
else {
tail = findTail(front);
tail.next = makeNode(num);
}
}
//add nodes after a specified node
public void addAfter(int num, node spot) {
node newNode;
newNode = makeNode(num);
newNode.next = spot.next;
spot.next = newNode;
}
//print out a list
public void showList(node front) {
node current = front;
while(current != null){
System.out.println(current.data);
current = current.next;
}
}
public static void main(String [] args) throws IOException{
//make a new list and node
LinkedList newList = new LinkedList();
node newNode = new node();
//add data to the nodes in the list
for(int j = 1; j < 10; j++){
newList.add2Back(newNode, j);
}
//print out the list of nodes
System.out.println("Auto-generated node list");
newList.showList(newNode);
//ask the user how many nodes to make, make those nodes, and show them
System.out.println("Please enter how many nodes you would like made.");
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in)) ;
String inputData = inputReader.readLine();
int listLength = Integer.parseInt(inputData);
LinkedList userList = new LinkedList();
node userNode = new node();
for(int j = 1; j < listLength; j++) {
userList.add2Back(userNode, j);
}
userList.showList(userNode);
//ask the user to add a new node to the list after a specified node
System.out.println("Please enter a number for a node and then choose a spot from the list to add after.");
BufferedReader inputReader2 = new BufferedReader(new InputStreamReader(System.in)) ;
String inputData2 = inputReader2.readLine();
BufferedReader inputReader3 = new BufferedReader(new InputStreamReader(System.in)) ;
String inputData3 = inputReader3.readLine();
int newNodeValue = Integer.parseInt(inputData2);
int nodeInList = Integer.parseInt(inputData3);
userList.addAfter(newNodeValue, userList.findSpot(userNode, nodeInList));
userList.showList(userNode);
//ask the user to delete a specified node
System.out.println("Please enter a node to delete.");
BufferedReader inputReader4 = new BufferedReader(new InputStreamReader(System.in)) ;
String inputData4 = inputReader4.readLine();
int nodeToDelete = Integer.parseInt(inputData4);
userList.deleteNode(userList.findSpot(userNode, nodeToDelete), userNode);
userList.showList(userNode);
}
}
The problem is that your deleteNode does not modify the front member variable of your list, because the front variable inside deleteNode is a method parameter, not the instance variable front.
Here is what you need to do:
Exposing front as a public member of the LinkedList is a violation of encapsulation. Make front a private variable.
Remove parameter front from all methods that take it; use the private member front instead.
Add a check in deleteNode to see if the spot to be deleted is the front. If it is, perform a special operation that assigns front a new value, and exit; otherwise, do the while loop that you already have.
public void deleteNode(node spot, node front) {
node current = spot, previous = front;
if(front == spot) {
front = null;
return;
}
while(previous.next != current) {
previous = previous.next;
}
previous.next = current.next;
current = null;
}
you are starting to check from the front.next. So front itself is being ignored each time.
Delete a node from linklist in PHP by just passing that value to
linklist delete method....
<?php
class ListNode
{
public $data;
public $next;
function __construct($data)
{
$this->data = $data;
$this->next = NULL;
}
function readNode()
{
return $this->data;
}
}
class LinkList
{
private $firstNode;
private $lastNode;
private $count;
function __construct()
{
$this->firstNode = NULL;
$this->lastNode = NULL;
$this->count = 0;
}
//deleting a node from linklist $key is the value you want to delete
public function deleteNode($key)
{
$current = $this->firstNode;
$previous = $this->firstNode;
while($current->data != $key)
{
if($current->next == NULL)
return NULL;
else
{
$previous = $current;
$current = $current->next;
}
}
if($current == $this->firstNode)
{
if($this->count == 1)
{
$this->lastNode = $this->firstNode;
}
$this->firstNode = $this->firstNode->next;
}
else
{
if($this->lastNode == $current)
{
$this->lastNode = $previous;
}
$previous->next = $current->next;
}
$this->count--;
}
}
$obj = new LinkList();
$obj->deleteNode($value);
}
?>
linklist delete method....
<?php
class ListNode
{
public $data;
public $next;
function __construct($data)
{
$this->data = $data;
$this->next = NULL;
}
function readNode()
{
return $this->data;
}
}
class LinkList
{
private $firstNode;
private $lastNode;
private $count;
function __construct()
}

deleteBack java program

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

Categories