Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to understand how Linked List data structures works, but in the past week after researching it and watching tutorials, I'm still confused. I'm trying to delete a node, when a node is not the head or the tail.
I'm working with a doubly linked list
My Linked List: [A]=[B]=[C]=[D]=[E]=[F]
I'm trying to delete Node B
This is my delete method
public GNode deleteNode(E e) {
GNode temp = new GNode(e); // This gets Node: [B]
GNode tempNext = temp.getNext(); // This gets Node: [C]
GNode tempPrevious = temp.getPrevious(); // This get Node: [A]
GNode current = findNode(temp, e); // This finds Node: [B]
// Deletes Head
if (this.head.getData().equals(e)) {
head = head.next;
head.previous = null;
this.size--;
}
// Delete Tail
if (this.tail.getData().equals(e)) {
tail = tail.previous;
tail.next = null;
this.size--;
}
// Delete Node
else {
if(findNode(temp,e) == e){
System.out.println("VALUE: " + temp.next);// Using this to debug. BUT temp.next returns null !?
tempPrevious.setNext(tempNext);
tempNext.setPrevious(tempPrevious);
size--;
}
}
return temp;
}
By doing some debugging I think I may not be initializing my variables correctly or looping through the list. Would anybody be able to point me to the right direction? And see what I may be doing wrong?
This is the entire code I'm working with
import java.io.*;
import java.util.*;
public class GDList<E> implements Cloneable {
private static class GNode<E> {
private E data;
private GNode<E> previous;
private GNode<E> next;
public GNode(E e) {
data = e;
previous = null;
next = null;
}
public E getData() {
return data;
}
public GNode getPrevious() {
return previous;
}
public GNode getNext() {
return next;
}
public void setData(E e) {
data = e;
}
public void setPrevious(GNode p) {
previous = p;
}
public void setNext(GNode p) {
next = p;
}
public Iterator<String> iterator() {
// TODO Auto-generated method stub
return null;
}
}
private GNode<E> head;
private GNode<E> tail;
private int size; // number of nodes in a list
public GDList() {
head = null;
tail = null;
size = 0;
}
public int addToHead(E e) {
GNode temp = new GNode(e);
if (head == null) {
head = temp;
tail = temp;
} else {
if (findNode(head, e) == null) {
temp.setNext(head);
head.setPrevious(temp);
head = temp;
} else
return 1;
}
size++;
return 0;
}
public int addToTail(E e) {
GNode temp = new GNode(e);
if (head == null) {
head = temp;
tail = temp;
} else {
if (findNode(head, e) == null) {
temp.setPrevious(tail);
tail.setNext(temp);
tail = temp;
} else
return 1;
}
size++;
return 0;
}
public int addAfter(GNode n, E e) {
if (n == null)
throw new IllegalArgumentException("The node n cannot be null");
if (findNode(head, e) != null)
return 1;
if (n == tail) {
addToTail(e);
} else {
GNode temp = new GNode(e); // element
GNode tempNext = n.getNext(); // location of element
temp.setNext(tempNext); // set element to the next location where
// the position is null
tempNext.setPrevious(temp); //
temp.setPrevious(n);
n.setNext(temp);
size++;
}
return 0;
}
public int addBefore(GNode n, E e) {
if (n == null)
throw new IllegalArgumentException("The node n c6annot be null");
if (findNode(head, e) != null)
return 1;
if (n == head)
addToHead(e);
else {
GNode temp = new GNode(e);
GNode tempPrevious = n.getPrevious();
temp.setNext(n);
n.setPrevious(temp);
tempPrevious.setNext(temp);
temp.setPrevious(tempPrevious);
size++;
}
return 0;
}
#SuppressWarnings("unchecked")
public GNode deleteNode(E e) {
// Linked List [22]=[3]=[17]=[9]
GNode prevNode = this.head;
GNode temp = new GNode(e); // Node: [17]
GNode tempNext = temp.getNext(); // Node: [9]
GNode tempPrevious = temp.getPrevious(); // Node: [3]
GNode current = findNode(temp, e); // Node: [17]
// Deletes Head
if (this.head.getData().equals(e)) {
head = head.next;
head.previous = null;
this.size--;
}
// Delete Tail
if (this.tail.getData().equals(e)) {
tail = tail.previous;
tail.next = null;
this.size--;
}
else {
if(findNode(temp,e) == e){
System.out.println("VALUE: " + temp.next);// Using this to debug. BUT temp.next returns null !?
tempPrevious.setNext(tempNext);
tempNext.setPrevious(tempPrevious);
size--;
}
}
return temp;
}
public GNode deleteAfter(E e) {
GNode temp = findNode(head, e);
if (temp == tail || temp == null)
return null;
return (deleteNode((E) temp.getNext().data));
}
public GNode deleteBefore(E e) {
GNode temp = findNode(head, e);
if (temp == head || temp == null)
return null;
return (deleteNode((E) temp.getPrevious().data));
}
public GNode findNode(GNode p, E e) {
GNode current = p; // current is the cursor
while (current != null && current.data != e) // while is not what I'm
// looking for
current = current.getNext();
return current;
}
public void printList() {
System.out.print("Number of nodes = " + size + ", List is: ");
if (head != null) {
GNode current = head;
while (current != null) {
System.out.print(current.data + " ");
current = current.getNext();
}
} else {
System.out.println("The list is empty");
}
System.out.println();
}
public static void main(String[] args) throws Exception {
GDList<String> names = new GDList<String>();
names.printList();
names.addToTail("A");
names.addToTail("B");
names.addToTail("C");
names.addToTail("D");
names.addToTail("E");
names.addToTail("F");
System.out.println();
// Delete Node
System.out.println();
System.out.println("\nDelete Node");
names.printList();
names.deleteNode("B"); // Delete B
names.printList();
}
}
When you create a new object GNode temp = new GNode(e);, temp.next and temp.previous is set to null. You can look at the constructor here.
public GNode(E e) {
data = e;
previous = null;
next = null;
}
You already have a method called findNode which is gonna simplify a lot of it.
public GNode deleteNode(E e) {
GNode current = findNode(head, e); // This finds Node: [B]
// a node with data e doesn't exist
if (current == null) {
return null;
}
// get the next and previous node
GNode previous = current.previous;
GNode next = current.next;
// current node is head
if (previous == null) {
this.head = current.next;
this.head.previous = null;
}
// current node is tail
if (next == null) {
this.tail = current.previous;
this.tail.next = null;
}
if (previous != null || next != null) {
GNode temp = current.previous;
temp.next = current.next;
temp = current.next;
temp.previous = current.previous;
}
return current;
}
Related
The code is working fine when I try to delete any element for some indices but for some others it is not working. For example, Whenever I try to delete by passing delete(1) it may work and if I try with delete(2) it may show NullPointerException. Here is the code :
Node head;
public void insert(int data)
{
Node node = new Node();
node.data = data;
node.next = null;
node.prev = null;
if(head == null)
{
head = node;
return;
}
Node n = head;
while(n.next!=null)
{
n = n.next;
}
node.prev = n;
n.next = node;
}
public void show()
{
if(head == null)
{
System.out.println("Doubly Linked List is empty so please enter values first.");
return;
}
Node n = head;
while(n.next!=null)
{
System.out.println(n.data);
n = n.next;
}
System.out.println(n.data);
}
public void delete(int index)
{
if(head == null)
{
System.out.println("List is empty.");
return;
}
if(index == 0)
{
head = head.next;
head.prev = null;
return;
}
Node n = head;
for(int i=0;i<index;i++)
{
n = n.next;
}
n.prev.next = n.next;
n.next.prev = n.prev;
}
}
So this is my code and You can see the delete method over there. I even run through debug mode, it is showing error at n.prev.next = n.next
Any kind of help is highly appreciated.
When I ran your code, the NullPointerException occurred on this line:
n.next.prev = n.prev;
and not on the line you said in your question.
The NullPointerException occurs when you delete the last Node in the list. This is because the value of next for the last Node in the list is null. So n.next is null and therefore n.next.prev throws NullPointerException.
You need to check whether n.next is null and only if it isn't you can execute the code: n.next.prev = n.prev.
Also, you need to check the value of parameter index in method delete(). One way would be to keep track of the number of elements in the list.
The below code incorporates the changes described. The parts I added are preceded by the comment Change here
public class DbLnkLst {
private static class Node {
int data;
Node next;
Node prev;
}
Node head;
public void insert(int data)
{
Node node = new Node();
node.data = data;
node.next = null;
node.prev = null;
if(head == null)
{
head = node;
return;
}
Node n = head;
while(n.next!=null)
{
n = n.next;
}
node.prev = n;
n.next = node;
}
public void show()
{
if(head == null)
{
System.out.println("Doubly Linked List is empty so please enter values first.");
return;
}
Node n = head;
while(n.next!=null)
{
System.out.println(n.data);
n = n.next;
}
System.out.println(n.data);
}
public void delete(int index)
{
// Change here.
if (index < 0) {
throw new IllegalArgumentException("negative index: " + index);
}
if(head == null)
{
System.out.println("List is empty.");
return;
}
if(index == 0)
{
head = head.next;
head.prev = null;
return;
}
Node n = head;
for(int i=0;i<index;i++)
{
// Change here.
if (n.next == null) {
throw new IllegalArgumentException("invalid index: " + index);
}
n = n.next;
}
n.prev.next = n.next;
// Change here.
if (n.next != null) {
n.next.prev = n.prev;
}
}
/**
* For testing the class.
*/
public static void main(String[] args) {
DbLnkLst list = new DbLnkLst();
list.insert(0);
list.insert(1);
list.insert(2);
System.out.println("List is:");
list.show();
list.delete(2);
System.out.println("After 'delete(2)', list is:");
list.show();
System.out.println("Try 'delete(2)' again.");
list.delete(2);
}
}
The output from running the above code is below:
List is:
0
1
2
After 'delete(2)', list is:
0
1
Try 'delete(2)' again.
Exception in thread "main" java.lang.IllegalArgumentException: invalid index: 2
at genrlprj/misctsts.DbLnkLst.delete(DbLnkLst.java:73)
at genrlprj/misctsts.DbLnkLst.main(DbLnkLst.java:100)
I'm using a generic linked list to implement priority queue where I use the comparable function for the insert function where it finds a slot where it's size is bigger than the current node. I have problem actually getting the add function insert the elements according priority queue requirements. The priority queue should go from smallest to biggest.
Edit: I realize the problem lies with inserting a number bigger than the head. During add 11, the function only compares with 5 and add it after 5 which ruins the sequence.
Current output
PQ: 5
PQ: 5,10
PQ: 5,9,10
PQ: 5,11,9,10
PQ: 5,7,11,9,10
PQ: 2,5,7,11,9,10
Desired output
PQ: 2,5,7,9,10,11
My add function
public class PQLinkedList<T extends Comparable<T>>{
private class Node{
private T data;
private Node next;
// Constructor that takes in data to input for the node
public Node(T data) {
this.data = data;
this.next = null;
}
}
private int length = 0;
private Node head;
int cmp = 0;
public PQLinkedList() {
head = null;
}
//Compare with each element till it finds a suitable position to insert itself
//Ascending order
//INCOMPLETE
//Compare part of this code is not complete!
public void addPQ( T data) {
Node node = new Node(data);
Node temp2 = null;
if ( head == null) {
addFirst(data);
}
else {
Node curr = head;
int count = getSize();
while ( count != 0) {
cmp = data.compareTo(curr.data);
if ( cmp < 0 ) {
addFirst(data);
break;
}
else if (cmp>=0 ){
if ( curr.next == null) {
curr.next = node;
break;
}
// if there curr.next is not empty
// Move all the nodes towards to tail by 1
else {
// after = one space after pos
// PROBLEM
temp2 = curr.next;
Node after = curr.next;
while( after != null) {
after = after.next;
}
node.next = temp2;
curr.next = node;
break;
}
}
else {
curr = curr.next;
}
count--;
}
}
length++;
}
private void addFirst(T data) {
Node node = new Node(data);
if ( head == null ) {
head = node;
}
else {
Node temp = head;
head = node;
node.next = temp;
}
length++;
}
//TO-DO
public void remove( T data) {
if ( !search(data)) {
System.out.println("Linked list does not contain that element!");
return;
}
else if ( head.data == data) {
head = head.next;
}
else {
// If curr is the node to be deleted.
// link from previous node to curr, link from curr to next node
//Traverse through the linkedlist till it finds the node to be deleted and skip it
Node curr = head;
while ( curr != null & curr.next != null ) {
if ( curr.next.data == data) {
//Check if the node 2 next after curr is null
//if so, remove curr.next which contains the value that we want to delete
if ( curr.next.next != null) {
curr.next = curr.next.next;
}
//curr.next.next is null so just curr.next which contains the value we want to delete
else {
curr.next = null;
}
}
//Traverse the curr node
else {
curr = curr.next;
}
}
length--;
}
}
// Retrieves and removes the head of the priority queue
public T poll() {
if ( isEmpty()) {
System.out.println("Linked list is empty!");
return null;
}
else {
Node temp = null;
temp = head ;
head = head.next;
length--;
return temp.data;
}
}
// Retrieves the head of the priority queue
public T peek() {
if ( isEmpty()) {
System.out.println("Linked list is empty!");
return null;
}
else {
return head.data;
}
}
public void clear() {
Node curr = head;
while ( curr != null) {
curr = curr.next;
}
}
public int getSize() {
return length;
}
public boolean search(T data) {
if ( isEmpty()) {
System.out.println("Linked list is empty!");
return false;
}
else {
Node node = head;
while ( node != null ) {
if ( node.data == data) {
return true;
}
node = node.next;
}
return false;
}
}
public boolean isEmpty() {
if ( length == 0) {
return true;
}
return false;
}
#Override
public String toString() {
String str = "PQ: ";
Node node = head;
while ( node != null) {
str = str + node.data;
if ( node.next != null) {
str = str + ",";
}
node = node.next;
}
return str;
}
}
My main
public class priorityQueueImplementation {
public static void main(String[] args) {
PQLinkedList<Integer> test = new PQLinkedList<Integer>();
test.add(5);
test.add(10);
test.add(9);
test.add(11);
test.add(7);
test.add(2);
System.out.println( test.toString());
}
}
Since this is a singly linked list, we cannot add node to previous node. We can only add to subsequent node. During node insertion, we need to compare data with the list. One every node, there are 5 cases:
current is null, data become the new head
data is smaller than current, data become the new head
data is greater than current, data is smaller then next. Insert data between current and next
data is greater than current, next is null. Insert data after current
data is greater than current, data is greater then next. Wait for next iteration
public void addPQ(T data) {
Node node = new Node(data);
Node curr = head;
if (head == null) {
// current is null, data become the new head
addFirst(data);
} else {
while (curr != null) {
int cmpLeft = data.compareTo(curr.data);
if (cmpLeft < 0) {
// data is smaller than current, `data` become the new head
addFirst(data);
break;
} else {
// data is greater than current
if (curr.next == null) {
// next is null. Insert `data` after `current`
addAfter(curr, node);
break;
} else {
int cmpRight = data.compareTo(curr.next.data);
if (cmpRight < 0) {
// data is smaller then next. Insert data between current and next
addAfter(curr, node);
break;
}
}
// data is greater then next. Wait for next iteration
curr = curr.next;
}
}
}
}
private void addAfter(Node currNode, Node newNode) {
if (currNode == null) {
currNode = newNode;
} else {
Node tempTail = currNode.next;
currNode.next = newNode;
newNode.next = tempTail;
}
length++;
}
output
PQ: 2,5,7,9,10,11
class StackNode{
int data;
StackNode next;
public StackNode(int data, StackNode next){
this.data = data;
this.next = next;
}
}
public class StackWithLinkedList {
StackNode root = null;
public void push(int data){
if(root == null)
root = new StackNode(data, null);
else {
StackNode temp = root;
while(temp.next != null)
temp = temp.next;
temp.next = new StackNode(data, null);
}
}
public int pop() throws Exception{
if(root == null)
throw new Exception("No Elements in Stack");
else {
StackNode temp = root;
while(temp.next != null)
temp = temp.next;
int data = temp.data;
temp = null;
return data;
}
}
public void print(){
StackNode temp = root;
while(temp!= null){
System.out.print(temp.data +" ");
temp = temp.next;
}
System.out.print("\n");
}
public static void main(String[] args) {
StackWithLinkedList stack = new StackWithLinkedList();
for(int i = 1; i<=15; i++){
Random randomGen = new Random();
stack.push(randomGen.nextInt(i));
}
stack.print();
System.out.print("\n");
try {
System.out.println("Deleted: "+stack.pop());
System.out.println("Deleted: "+stack.pop());
} catch (Exception e) {
e.printStackTrace();
}
stack.print();
}
}
I am trying to implement Stack with Linkedlist. In pop function i am traversing till the last node and making it null. When i print the list. it remain unchanged. Does assigning root to temp and traversing with it cause any problem?
You can avoid this all together by simplifying your implementation. It's just a stack so it's LIFO. All you need to do is make the last element push-ed the root. When pop-ing return the data in root and set root to the next in line.
The way you're doing it increases the typical complexity of O(1) to O(N) for the push and pop operations.
Something like:
public void push(int data) {
root = new StackNode(data, root);
}
public int pop() throws Exception {
if (root == null)
throw new Exception("No Elements in Stack");
else {
int data = root.data;
root = root.next;
return data;
}
}
As mentioned in other answer by #ChiefTwoPencils, that must be the preferred way of implementing this. However, to correct your logic of pop operation you shall keep track of second last item and once you get that you can return data value of next node and set the next link to null.
Here is changed logic from your code of pop method
public int pop() throws Exception{
if(root == null)
throw new Exception("No Elements in Stack");
else {
int data = -1;
if(root.next==null) {
data = root.data;
root = null;
return data;
}
StackNode temp = root;
while(temp.next.next != null)
temp = temp.next;
data = temp.next.data;
temp.next = null;
return data;
}
}
Hope it helps.
public int pop() throws Exception{
if(root == null)
throw new Exception("No Elements in Stack");
else {
StackNode temp = root;
StackNode prev;
while(temp.next != null){
prev = temp;
temp = temp.next;
}
int data = temp.data;
prev.next = null;
return data;
}
}
This is a class lab, and within it I am attempting to add, remove, etc. into a doubly linked list. I have what I believe to be correct with what I have. I am having problems figuring out how to remove an object if its not the beginning or end of the list. I am having similar issues with the add method. Any advice on where to go from here and comments on my current code is very appreciated.
public class Double<T extends Comparable<T>> implements ListInterface<T> {
protected DLLNode<T> front; //Front of list
protected DLLNode<T> rear; //Rear of list
protected DLLNode<T> curPosition; //Current spot for iteration
protected int numElements; //Number of elements in list
public Double() {
front = null;
rear = null;
curPosition = null;
numElements = 0;
}
protected DLLNode<T> find(T target) {
//While the list is not empty and the target is not equal to the current element
//curr will move down the list. If curr becomes null then return null.
//If it finds the element, return it.
DLLNode<T> curr;
curr = front;
T currInfo = curr.getInfo();
while(curr != null && currInfo.compareTo(target) != 0) {
curr = (DLLNode<T>)curr.getLink();
}
if (curr == null) {
return null;
}
else {
return curr;
}
}
public int size() {
//Return number of elements in the list
return numElements;
}
public boolean contains(T element) {
//Does the list contain the given element?
//Return true if so, false otherwise.
if (find(element) == null) {
return false;
}
else {
return true;
}
}
public boolean remove(T element) {
//While the list is not empty, curr will move down. If the element can not
//be found, then return false. Else remove the element.
DLLNode<T> curr;
curr = front;
T currInfo = curr.getInfo();
while(curr != null) {
curr = (DLLNode<T>)curr.getLink();
}
if (find(element) == null) {
return false;
}
else {
if (curr == null) {
curr = curr.getBack();
curr = rear;
}
else if (curr == front) {
curr = (DLLNode<T>)curr.getLink();
curr = front;
}
else if (curr == rear) {
curr = curr.getBack();
curr = rear;
}
else {
}
return true;
}
}
public T get(T element) {
//Return the info of the find method.
if (find(element) == null) {
return null;
}
else {
return find(element).getInfo();
}
}
//public String toString() {
//}
public void reset() {
//Reset the iteration back to front
curPosition = front;
}
public T getNext() {
//Return the info of the next element in the list
DLLNode<T> curr;
curr = front;
//while (curr != null) {
//curr = (DLLNode<T>)curr.getLink();
//}
if ((DLLNode<T>)curr.getLink() == null) {
return null;
}
else {
curr = (DLLNode<T>)curr.getLink();
return curr.getInfo();
}
}
public void resetBack() {
}
public T getPrevious() {
//Return the previous element in the list
DLLNode<T> curr;
curr = front;
if ((DLLNode<T>)curr.getLink() == null) {
return null;
}
else if((DLLNode<T>)curr.getBack() == null) {
return null;
}
else {
curr = curr.getBack();
return curr.getInfo();
}
}
public void add(T element) {
//PreCondition: Assume the element is NOT already in the list
//AND that the list is not full!
DLLNode<T> curr;
DLLNode<T> newNode = (DLLNode<T>)element;
curr = front;
if (curr == null) {
front = (DLLNode<T>)element;
}
else {
}
}
}
This is the target main function eventually:
public static void main(String[] args){
Double<String> d = new Double<String>();
d.add("Hello");
d.add("Arthur");
d.add("Goodbye");
d.add("Zoo");
d.add("Computer Science");
d.add("Mathematics");
d.add("Testing");
System.out.println(d);
System.out.println( "Contains -Hello- " + d.contains("Hello"));
System.out.println("Contains -Spring- " + d.contains("Spring"));
System.out.println("size: " + d.size());
d.resetBack();
for (int i = 0; i < d.size(); i++){
String item = (String)d.getPrevious();
System.out.println(item);
} //good stopping point
d.remove("Zoo");
d.remove("Arthur");
d.remove("Testing");
System.out.println("size: " + d.size());
System.out.println(d);
d.remove("Goodbye");
d.remove("Hello");
System.out.println(d);
d.remove ("Computer Science");
d.remove("Mathematics");
System.out.println(d);}
}
I don't know what your DLLNode class looks like, but it probably looks like
class DLLNode {
DLLNode next;
DLLNode prev;
}
To remove a node, the logic would be
next.prev = prev;
prev.next = next;
To add a node newNode following a node, the logic is
newNode.prev = this;
newNode.next = next;
next = newNode;
I haven't done any null pointer checks, that's up to you.
I have a project where I have to write a bunch of sort methods and measure the time complexity for each, and output the results to an output text file. the program runs but i get some null pointer exceptions in bubblesort method. here is my code and error, if you can tell me how to fix my sort methods, that would be awesome!
linked list class:
public class LinkedList {
protected static class Node {
Comparable item;
Node prev, next;
public Node(Comparable newItem, Node prev, Node next) {
this.item = newItem;
this.prev = prev;
this.next = next;
}
public Node (Comparable newItem) {
this(newItem, null, null);
}
public Node() {
this(null, null, null);
}
public String toString() {
return String.valueOf(item);
}
}
private Node head;
private int size;
public int dataCompares, dataAssigns;
public int loopCompares, loopAssigns;
public int other;
public LinkedList() {
head = new Node(null, null, null);
head.prev = head;
head.next = head;
size = 0;
}
public boolean add(Comparable newItem) {
Node newNode = new Node(newItem);
Node curr;
if(isEmpty()) {
head.next = newNode;
head.prev = newNode;
newNode.next = head;
newNode.prev = head;
} else {
newNode.next = head;
newNode.prev = head.prev;
head.prev.next = newNode;
head.prev = newNode;
}
size++;
return false;
}
public boolean remove(Comparable item) {
if(!isEmpty()) {
Node prev = null;
Node curr = head;
while(curr!=null) {
if(curr.item.compareTo(item)==0) {
if(prev==null) {
head=curr.next;
} else {
prev.next = curr.next;
curr=curr.next;
}
size--;
return true;
}else{
prev=curr;
curr = curr.next;
}
}
}
return false;
}
public void removeAll() {
this.head.prev = null;
this.head.next = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public boolean remove(Object item) {
return true;
}
public void insertSortNode() {
Node back = head;
if (size < 2)
return;
back = back.next; // SECOND entry in the list
while ( back != null ) { // I.e., end-of-list
Comparable value = back.item;
Node curr = head; // Start at the front
// Find insertion point for value;
while (curr != back && value.compareTo(curr.item) >= 0)
curr = curr.next;
// Propogate values upward, inserting the value from back
while (curr != back){
Comparable hold = curr.item;
curr.item = value;
value = hold;
curr = curr.next;
}
back.item = value; // Drop final value into place!
back = back.next; // Move sorted boundary up
}
} // end insertSort()
public void selSort() {
Node front = head;
// Nothing to do on an empty list
if ( front == null )
return;
while ( front.next != null ) { // skips a one-entry list
Node tiny = front;
Node curr = front.next;
Comparable temp = front.item; // start the swap
for ( ; curr != null ; curr = curr.next ) {
if ( tiny.item.compareTo(curr.item) > 0 )
tiny = curr;
}
front.item = tiny.item; // Finish the swap
tiny.item = temp;
front = front.next; // Advance to the next node
}
// The structure is unchanged, so the validity of tail is unchanged.
}
public void bubbleSort() {
Node Trav=head.next;
Node Trail=head.next;
Comparable temp;
if (Trav != null)
Trav = Trav.next;
while(Trav!=null) {
if (Trav.item.compareTo(Trail.item)<0) {
temp = Trail.item;
Trail.item=Trav.item;
Trav.item = temp;
}
Trail=Trav;
Trav=Trav.next;
}
}
public void insertSortArray() {
Node insert1, cur, tmp1;
Comparable temp;
for(insert1 = this.head.next.next; insert1!=this.head; insert1 = insert1.next) {
//++loopcompares; ++loopassigns;
for (cur = head.next; cur!=insert1; cur=cur.next) {
//++loopCompares; ++loopassigns;
//++datacompares;
if(insert1.item.compareTo(cur.item)<0) {
temp=insert1.item;
//++dataassign
tmp1=insert1;
//++other
while(tmp1!=cur.prev) {
//++loopcomares
tmp1.item=tmp1.prev.item;
tmp1=tmp1.prev;
//++dataassign+=2
}
//++loopcompares
cur.item = temp;
//++dataassign;
break;
}
}
//++loopcompares; ++loopassigns;
}
//++loopcompares; ++loopassigns
}
public void disp6sortsFile(boolean disp, String fileName, String header, String data) {
FileWriter fw = null;
PrintWriter pw = null;
try {
File file = new File(fileName);
fw = new FileWriter(file, true);
pw = new PrintWriter(fw, true);
} catch (IOException e) {
System.err.println("File open failed for " +fileName+ "\n" + e);
System.exit(-1);
}
if (disp) {
pw.print(header + "\n");
}
pw.print(data + "\n");
pw.close();
}
}
here is my error:
Exception in thread "main" java.lang.NullPointerException
at LinkedList.bubbleSort(LinkedList.java:149)
at LinkListTester.main(LinkListTester.java:51)
the linkedlisttester error is simply list1.bubbleSort(); so bubble sort is the problem.
Change:
public String toString() {
return this.item.toString();
}
to:
public String toString() {
return String.valueOf(item); // Handle null too.
}
For add return true. Might check that item is not null if so desired.
remove is written for a single linked list.
In remove the head has a null item, which might have caused the error. Also as we have a circular list with a dummy node for head, the termination should not test for null but head. Otherwise a not present item will loop infinitely.
public boolean remove(Comparable item) {
if(!isEmpty()) {
Node prev = null;
Node curr = head.next; // !
while(curr!=head) { // !
if(curr.item.compareTo(item)==0) {
if(prev==null) { // ! WRONG, but I will not correct home work ;)
head=curr.next;
} else {
prev.next = curr.next;
curr=curr.next;
}
size--;
return true;
}else{
prev=curr;
curr = curr.next;
}
}
}
return false;
}
swap is written for a single linked list.
And here I stopped reading, as I've come to the usages.
Second Edit:
All algorithmic functions, i.e. bubbleSort, have the following control flow:
while(Trav!=null) { ... Trav = Trav.next; }
But the data structure is defined cyclic, so eventually you arrive back at head and there the item is null.
The solution is to have for the first Node a prev null, and for the last Node a next null.
To make this clear, readable, you could substitute the Node head with:
Node first;
Node last;