I'm trying to work on a method that will insert the node passed to it before the current node in a linked list. It has 3 conditions. For this implementation there cannot be any head nodes (only a reference to the first node in the list) and I cannot add any more variables.
If the list is empty, then set the passed node as the first node in the list.
If the current node is at the front of the list. If so, set the passed node's next to the current node and set the first node as the passed node to move it to the front.
If the list is not empty and the current is not at the front, then iterate through the list until a local node is equal to the current node of the list. Then I carry out the same instruction as in 2.
Here is my code.
public class LinkedList
{
private Node currentNode;
private Node firstNode;
private int nodeCount;
public static void main(String[] args)
{
LinkedList test;
String dataTest;
test = new LinkedList();
dataTest = "abcdefghijklmnopqrstuvwxyz";
for(int i=0; i< dataTest.length(); i++) { test.insert(new String(new char[] { dataTest.charAt(i) })); }
System.out.println("[1] "+ test);
for(int i=0; i< dataTest.length(); i++) { test.deleteCurrentNode(); }
System.out.println("[2] "+test);
for(int i=0; i< dataTest.length(); i++)
{
test.insertBeforeCurrentNode(new String(new char[] { dataTest.charAt(i) }));
if(i%2 == 0) { test.first(); } else { test.last(); }
}
System.out.println("[3] "+test);
}
public LinkedList()
{
setListPtr(null);
setCurrent(null);
nodeCount = 0;
}
public boolean atEnd()
{
checkCurrent();
return getCurrent().getNext() == null;
}
public boolean isEmpty()
{
return getListPtr() == null;
}
public void first()
{
setCurrent(getListPtr());
}
public void next()
{
checkCurrent();
if (atEnd()) {throw new InvalidPositionInListException("You are at the end of the list. There is no next node. next().");}
setCurrent(this.currentNode.getNext());
}
public void last()
{
if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}
while (!atEnd())
{
setCurrent(getCurrent().getNext());
}
}
public Object getData()
{
return getCurrent().getData();
}
public void insertBeforeCurrentNode(Object bcNode) //beforeCurrentNode
{
Node current;
Node hold;
boolean done;
hold = allocateNode();
hold.setData(bcNode);
current = getListPtr();
done = false;
if (isEmpty())
{
setListPtr(hold);
setCurrent(hold);
}
else if (getCurrent() == getListPtr())
{
System.out.println("hi" + hold);
hold.setNext(getCurrent());
setListPtr(hold);
}
else //if (!isEmpty() && getCurrent() != getListPtr())
{
while (!done && current.getNext() != null)
{
System.out.println("in else if " + hold);
if (current.getNext() == getCurrent())
{
//previous.setNext(hold);
//System.out.println("hi"+ "yo" + " " + getListPtr());
hold.setNext(current.getNext());
current.setNext(hold);
done = true;
}
//previous = current;
current = current.getNext();
}
}
System.out.println(getCurrent());
}
public void insertAfterCurrentNode(Object acNode) //afterCurrentNode
{
Node hold;
hold = allocateNode();
hold.setData(acNode);
if (isEmpty())
{
setListPtr(hold);
setCurrent(hold);
//System.out.println(hold + " hi");
}
else
{
//System.out.println(hold + " hia");
hold.setNext(getCurrent().getNext());
getCurrent().setNext(hold);
}
}
public void insert(Object iNode)
{
insertAfterCurrentNode(iNode);
}
public Object deleteCurrentNode()
{
Object nData;
Node previous;
Node current;
previous = getListPtr();
current = getListPtr();
nData = getCurrent().getData();
if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}
else if (previous == getCurrent())
{
getListPtr().setNext(getCurrent().getNext());
setCurrent(getCurrent().getNext());
nodeCount = nodeCount - 1;
}
else
{
while (previous.getNext() != getCurrent())
{
previous = current;
current = current.getNext();
}
previous.setNext(getCurrent().getNext());
setCurrent(getCurrent().getNext());
nodeCount = nodeCount - 1;
}
return nData;
}
public Object deleteFirstNode(boolean toDelete)
{
if (toDelete)
{
setListPtr(null);
}
return getListPtr();
}
public Object deleteFirstNode()
{
Object deleteFirst;
deleteFirst = deleteFirstNode(true);
return deleteFirst;
}
public int size()
{
return this.nodeCount;
}
public String toString()
{
String nodeString;
Node sNode;
sNode = getCurrent();
//System.out.println(nodeCount);
nodeString = ("List contains " + nodeCount + " nodes");
while (sNode != null)
{
nodeString = nodeString + " " +sNode.getData();
sNode = sNode.getNext();
}
return nodeString;
}
private Node allocateNode()
{
Node newNode;
newNode = new Node();
nodeCount = nodeCount + 1;
return newNode;
}
private void deAllocateNode(Node dNode)
{
dNode.setData(null);
}
private Node getListPtr()
{
return this.firstNode;
}
private void setListPtr(Node pNode)
{
this.firstNode = pNode;
}
private Node getCurrent()
{
return this.currentNode;
}
private void setCurrent(Node cNode)
{
this.currentNode = cNode;
}
private void checkCurrent()
{
if (getCurrent() == null) {throw new InvalidPositionInListException("Current node is null and is set to an invalid position within the list! checkCurrent()");}
}
/**NODE CLASS ----------------------------------------------*/
private class Node
{
private Node next; //serves as a reference to the next node
private Object data;
public Node()
{
this.next = null;
this.data = null;
}
public Object getData()
{
return this.data;
}
public void setData(Object obj)
{
this.data = obj;
}
public Node getNext()
{
return this.next;
}
public void setNext(Node nextNode)
{
this.next = nextNode;
}
public String toString()
{
String nodeString;
Node sNode;
sNode = getCurrent();
//System.out.println(nodeCount);
nodeString = ("List contains " + nodeCount + " nodes");
while (sNode != null)
{
nodeString = nodeString + " " +sNode.getData();
sNode = sNode.getNext();
}
return nodeString;
}
}
}
I have it working for my [1] and [2] conditions. But my [3] (that tests insertBeforeCurrentNode()) isn't working correctly. I've set up print statements, and I've determined that my current is reset somewhere, but I can't figure out where and could use some guidance or a solution.
The output for [1] and [2] is correct. The output for [3] should read
[3] List contains 26 nodes: z x v t r p n l j h f d b c e g i k m o q s u w y a
Thanks for any help in advance.
In your toString method you start printing nodes from the currentNode till the end of your list. Because you call test.last() just before printing your results, the currentNode will point on the last node of the list, and your toString() will only print 'a'.
In your toString() method, you may want to change
sNode = getCurrent();
with
sNode = getListPtr();
to print your 26 nodes.
For [3] you need to keep pointers to two nodes: one pointer in the "current" node, the one you're looking for, and the other in the "previous" node, the one just before the current. In that way, when you find the node you're looking in the "current" position, then you can connect the new node after the "previous" and before the "current". In pseudocode, and after making sure that the cases [1] and [2] have been covered before:
Node previous = null;
Node current = first;
while (current != null && current.getValue() != searchedValue) {
previous = current;
current = current.getNext();
}
previous.setNext(newNode);
newNode.setNext(current);
Related
I need your help with implementing the correct sorting algorithm for Priority Queue. Apparently I've done this wrong as it creates a duplicate node. I'm stumped on this, any help would be greatly appreciated. I need to get this right as I will use this on both increase() and decrease() methods.
Check my sort() method below in the code.
Here is my code:
public class PriorityQueueIntegers implements PriorityQueueInterface {
// number of elements
private int numberOfElements;
// element
private int element;
// priority
private int priority;
// Node
Node head = null, tail = null;
// returns true if the queue is empty (no items in queue)
// false if queue is (has at least one or more items in queue)
public boolean isEmpty()
{
return ( numberOfElements == 0 );
}
// returns the value of the item currently at front of queue
public int peek_frontValue()
{
return head.getValue(); // return the value in the head node
}
// returns the priority of the item currently at front of queue
public int peek_frontPriority()
{
return head.getPriority();
}
// clear the queue
public void clear()
{
head = null;
tail = null;
numberOfElements = 0;
}
// insert the item with element and priority
public void insert(int newElement, int newPriority)
{
// if head node is null, make head and tail node contain the first node
if (head == null)
{
head = new Node(newElement, newPriority);
tail=head; // when first item is enqueued, head and tail are the same
}
else
{
Node newNode = new Node(newElement, newPriority);
tail.setNext(newNode);
tail=newNode;
}
sort(newElement, newPriority);
numberOfElements++;
}
public void increase(int findElement, int priority_delta)
{
Node current = head;
if (numberOfElements > 0)
{
while (current != null)
{
if (current.getValue() == findElement)
{
int newPriority = current.getPriority() + priority_delta;
current.setIncreasePriority(newPriority);
}
current = current.getNext();
}
} else throw new UnsupportedOperationException("Empty Queue - increase failed");
}
public void decrease(int findElement, int priority_delta)
{
Node current = head;
if (numberOfElements > 0)
{
while (current != null)
{
if (current.getValue() == findElement)
{
int newPriority = current.getPriority() - priority_delta;
if (newPriority < 0)
{
throw new UnsupportedOperationException("Can't be a negative number");
}
current.setDecreasePriority(newPriority);
}
current = current.getNext();
}
} else throw new UnsupportedOperationException("Empty Queue - increase failed");
}
private void sort(int value, int priority)
{
Node current = head;
int v = value;
int p = priority;
Node temp = new Node(v, p);
if (numberOfElements > 0)
{
while (current != null && current.getNext().getPriority() < p)
{
current = current.getNext();
}
temp._next = current._next;
current._next = temp;
}
}
public int remove_maximum()
{
int headDataValue = 0;
if ( numberOfElements > 0 )
{
headDataValue = head.getValue();
Node oldHead=head;
head=head.getNext();
oldHead.setNext(null);
this.numberOfElements--;
}
else throw new UnsupportedOperationException("Empty Queue - dequeue failed");
return headDataValue; // returns the data value from the popped head, null if queue empty
}
public String display()
{
Node current = head;
String result = "";
if ( current == null )
{
result = "[Empty Queue]";
}
else
{
while ( current != null )
{
result = result + "[" + current.getValue() + "," + current.getPriority() + "] ";
current = current.getNext();
}
}
return result;
}
//////////////////////////////////////////////////////////////
// Inner Node Class
private class Node
{
private int value;
private int priority;
private Node _next;
public Node (int element, int priority_delta)
{
this.value = element;
this.priority = priority_delta;
_next = null;
}
protected Node(int element, int priority_delta, Node nextNode)
{
this.value = element;
this.priority = priority_delta;
_next = nextNode;
}
public Node getNext()
{
return _next;
}
public int getValue()
{
return this.value;
}
public int getPriority()
{
return this.priority;
}
public void setIncreasePriority(int newPriority)
{
this.priority = newPriority;
}
public void setDecreasePriority(int newPriority)
{
this.priority = newPriority;
}
public void setNext(Node newNextNode)
{
_next = newNextNode;
}
}
}
You are correct that your code currently creates duplicate nodes. Your insert method creates a node:
if (head == null) {
head = new Node(newElement, newPriority);
tail=head; // when first item is enqueued, head and tail are the same
} else {
Node newNode = new Node(newElement, newPriority);
tail.setNext(newNode);
tail=newNode;
}
This method then calls sort that also creates a node:
Node temp = new Node(v, p);
if (numberOfElements > 0) {
while (current != null && current.getNext().getPriority() < p) {
current = current.getNext();
}
temp._next = current._next;
current._next = temp;
}
It does not make a lot of sense to me that a sort method would create a new node. You should either insert the node in the right position in insert or the sort method should move it to the correct position. If you take the first approach then you'll need to change you increase and decrease methods.
A potential method to move a node to the correct position, in pseduocode, would be:
move node:
walk through queue and find both
node that's next points to the one you are moving (from)
last node that has higher priority than the one you are moving (to)
set from.next to node.next
set node.next to to.next
set to.next to node
import java.util.*;
public class ListStack extends LinkedList{
public ListStack() { // <== constructor, different from ListStackComp.java
super();
}
public boolean empty() {
if(isEmpty()){
return true;
}else{
return false;
}
}
public Object push(Object item) {
addToHead(item);
return item;
}
public Object pop() {
Object item = removeFromHead();
return item;
}
public Object peek() {
Object item = get(0);
return item;
}
public int search(Object item) {
ListNode current = head;
int num=-1;
for(int i = 0;i<length;i++){
if(item.equals(current.getData())){
num = i;
}
else{
current = current.getNext();
}
}
return num;
}
}
The result is:
[ 789.123 E Patrick 123 Dog Cat B A ]
peek() returns: 789.123
Patrick is at 7
A is at 7
789.123 is at 7
Peter is at -1
Can help me to solve the problem? Does search() have some error?
class ListNode {
private Object data;
private ListNode next;
ListNode(Object o) { data = o; next = null; }
ListNode(Object o, ListNode nextNode)
{ data = o; next = nextNode; }
public void setData(Object data){
this.data = data;
}
public void setNext(ListNode next){
this.next = next;
}
public Object getData() { return data; }
public ListNode getNext() { return next; }
} // class ListNode
class EmptyListException extends RuntimeException {
public EmptyListException () { super ("List is empty"); }
} // class EmptyListException
class LinkedList {
protected ListNode head; // <== chnage to protected for inheriting
protected ListNode tail; // <== change to protected for inheriting
protected int length; // the length of the list <== chnage to protected for inheriting
public LinkedList() {
head = tail = null;
length = 0;
}
public boolean isEmpty() { return head == null; }
public void addToHead(Object item) {
if (isEmpty())
head = tail = new ListNode(item);
else
head = new ListNode(item, head);
length++;
}
public void addToTail(Object item) {
if (isEmpty())
head = tail = new ListNode(item);
else {
tail.setNext(new ListNode(item));
tail = tail.getNext();
}
length++;
}
public Object removeFromHead() throws EmptyListException {
Object item = null;
if (isEmpty())
throw new EmptyListException();
item = head.getData();
if (head == tail)
head = tail = null;
else
head = head.getNext();
length--;
return item;
}
public Object removeFromTail() throws EmptyListException {
Object item = null;
if (isEmpty())
throw new EmptyListException();
item = tail.getData();
if (head == tail)
head = tail = null;
else {
ListNode current = head;
while (current.getNext() != tail)
current = current.getNext();
tail = current;
current.setNext(null);
}
length--;
return item;
}
public String toString() {
String str = "[ ";
ListNode current = head;
while (current != null) {
str = str + current.getData() + " ";
current = current.getNext();
}
return str + " ]";
}
public int count() {
return length;
}
public Object remove(int n) {
Object item = null;
if (n <= length) { // make sure there is nth node to remove
// special treatment for first and last nodes
if (n == 1) return removeFromHead();
if (n == length) return removeFromTail();
// removal of nth node which has nodes in front and behind
ListNode current = head;
ListNode previous = null;
for (int i = 1; i < n; i++) { // current will point to nth node
previous = current;
current = current.getNext();
}
// data to be returned
item = current.getData();
// remove the node by adjusting two pointers (object reference)
previous.setNext(current.getNext());
}
length--;
return item;
}
public void add(int n, Object item) {
// special treatment for insert as first node
if (n == 1) {
addToHead(item);
return;
}
// special treatment for insert as last node
if (n > length) {
addToTail(item);
return;
}
// locate the n-1th node
ListNode current = head;
for (int i = 1; i < n-1; i++) // current will point to n-1th node
current = current.getNext();
// create new node and insert at nth position
current.setNext(new ListNode(item, current.getNext()));
length++;
}
public Object get(int n) {
// n is too big, no item can be returned
if (length < n) return null;
// locate the nth node
ListNode current = head;
for (int i = 1; i < n; i++)
current = current.getNext();
return current.getData();
}
} // class LinkedList
import java.util.Stack;
import java.util.Iterator;
public class TestStack {
public static void main (String args[]) {
ListStack s = new ListStack();
System.out.println(s);
System.out.println("Patrick is at " + s.search("Patrick"));
s.push(new Character('A'));
System.out.println(s);
s.push(new Character('B'));
System.out.println(s);
s.push("Cat");
System.out.println(s);
s.push("Dog");
System.out.println(s);
s.push(new Integer(123));
System.out.println(s);
s.push("Patrick");
System.out.println(s);
s.push(new Character('E'));
System.out.println(s);
s.push(new Double(789.123));
System.out.println(s);
System.out.println("peek() returns: " + s.peek());
System.out.println("Patrick is at " + s.search("Patrick"));
System.out.println("A is at " + s.search(new Character('A')));
System.out.println("789.123 is at " + s.search(new Double(789.123)));
System.out.println("Peter is at " + s.search("Peter"));
System.out.println();
}
} // class TestStack
There is another code of LinkedList and Test file
public int search(Object item) {
ListNode current = head;
int num=-1;
for(int i = 0;i<length;i++){
if(item.equals(current.getData())){
return i;
}
else{
current = current.getNext();
}
}
return num;
}
Hope It will work.
public Object peek() {
Object item = get(0);
return item;
}
public int search(Object item) {
ListNode current = head;
int num=-1;
for(int i = 1;i<length;i++){
if(item.equals(current.getData())){
num = i;
return num;
}
else{
current = current.getNext();
}
}
return num;
}
There is new problem in the result:
[ A B Cat Dog 123 Patrick E 789.123 ]
peek() returns: A
Patrick is at 6
A is at 1
789.123 is at -1
Peter is at -1
Why the result cannot find 789.123?
The peek() method how can I improve that can find 789.123 is top?
I was doing this exercice:
Write code to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x. Example input: 3 -> 5 -> 8 -> 5 -> 10 -> 2 -> 1 output: 3 -> 1 -> 2 -> 10 -> 5 -> 5 -> 8
I found it hard to find a solution for Singly linked list (that created by my own, not using library), I would like to know if there is uncessary code blocks in my code and is there a way to avoid putting in two lists and then merge? because it seems to have very slow performance like that.
public CustomLinkedList partition(CustomLinkedList list, int x) {
CustomLinkedList beforeL = new CustomLinkedList();
CustomLinkedList afterL = new CustomLinkedList();
LinkedListNode current = list.getHead();
while (current != null) {
if (current.getData() < x) {
addToLinkedList(beforeL, current.getData());
} else {
addToLinkedList(afterL, current.getData());
}
// increment current
current = current.getNext();
}
if (beforeL.getHead() == null)
return afterL;
mergeLinkedLists(beforeL, afterL);
return beforeL;
}
public void addToLinkedList(CustomLinkedList list, int value) {
LinkedListNode newEnd = new LinkedListNode(value);
LinkedListNode cur = list.getHead();
if (cur == null)
list.setHead(newEnd);
else {
while (cur.getNext() != null) {
cur = cur.getNext();
}
cur.setNext(newEnd);
cur = newEnd;
}
}
public void mergeLinkedLists(CustomLinkedList list1, CustomLinkedList list2) {
LinkedListNode start = list1.getHead();
LinkedListNode prev = null;
while (start != null) {
prev = start;
start = start.getNext();
}
prev.setNext(list2.getHead());
}
CustumLinkedList contains two attributes: -LinkedListNode which is the head and an int which is the size.
LinkedListNode contains two attributes: One of type LinkedListNode pointing to next node and one of type int: data value
Thank you.
The problem of your code is not merging two lists as you mentioned. It's wrong to use the word merge here because you're only linking up the tail of the left list with head of right list which is a constant time operation.
The real problem is - on inserting a new element on the left or right list, you are iterating from head to tail every time which yields in-total O(n^2) operation and is definitely slow.
Here I've wrote a simpler version and avoid iterating every time from head to insert a new item by keeping track of the current tail.
The code is very simple and is definitely faster than yours(O(n)). Let me know if you need explanation on any part.
// I don't know how your CustomLinkedList is implemented. Here I wrote a simple LinkedList node
public class ListNode {
private int val;
private ListNode next;
public ListNode(int x) {
val = x;
}
public int getValue() {
return this.val;
}
public ListNode getNext() {
return this.next;
}
public void setNext(ListNode next) {
this.next = next;
}
}
public ListNode partition(ListNode head, int x) {
if(head == null) return null;
ListNode left = null;
ListNode right = null;
ListNode iterL = left;
ListNode iterR = right;
while(iter != null) {
if(iter.getValue() < x) {
iterL = addNode(iterL, iter.getValue());
}
else {
iterR = addNode(iterR, iter.getValue());
}
iter = iter.getNext();
}
// link up the left and right list
iterL.setNext(iterR);
return left;
}
public ListNode addNode(ListNode curr, int value) {
ListNode* newNode = new ListNode(value);
if(curr == null) {
curr = newNode;
} else {
curr.setNext(newNode);
curr = curr.getNext();
}
return curr;
}
Hope it helps!
If you have any list of data, access orderByX Method.
Hope it would help you.
public class OrderByX {
Nodes root = null;
OrderByX() {
root = null;
}
void create(int[] array, int k) {
for (int i = 0; i < array.length; ++i) {
root = insert(root, array[i]);
}
}
Nodes insert(Nodes root, int data) {
if (root == null) {
root = new Nodes(data);
} else {
Nodes tempNew = new Nodes(data);
tempNew.setNext(root);
root = tempNew;
}
return root;
}
void display() {
Nodes tempNode = root;
while (tempNode != null) {
System.out.print(tempNode.getData() + ", ");
tempNode = tempNode.getNext();
}
}
void displayOrder(Nodes root) {
if (root == null) {
return;
} else {
displayOrder(root.getNext());
System.out.print(root.getData() + ", ");
}
}
Nodes orderByX(Nodes root, int x) {
Nodes resultNode = null;
Nodes lessNode = null;
Nodes greatNode = null;
Nodes midNode = null;
while (root != null) {
if (root.getData() < x) {
if (lessNode == null) {
lessNode = root;
root = root.getNext();
lessNode.setNext(null);
} else {
Nodes temp = root.getNext();
root.setNext(lessNode);
lessNode = root;
root = temp;
}
} else if (root.getData() > x) {
if (greatNode == null) {
greatNode = root;
root = root.getNext();
greatNode.setNext(null);
} else {
Nodes temp = root.getNext();
root.setNext(greatNode);
greatNode = root;
root = temp;
}
} else {
if (midNode == null) {
midNode = root;
root = root.getNext();
midNode.setNext(null);
} else {
Nodes temp = root.getNext();
root.setNext(midNode);
midNode = root;
root = temp;
}
}
}
resultNode = lessNode;
while (lessNode.getNext() != null) {
lessNode = lessNode.getNext();
}
lessNode.setNext(midNode);
while (midNode.getNext() != null) {
midNode = midNode.getNext();
}
midNode.setNext(greatNode);
return resultNode;
}
public static void main(String... args) {
int[] array = { 7, 1, 6, 2, 8 };
OrderByX obj = new OrderByX();
obj.create(array, 0);
obj.display();
System.out.println();
obj.displayOrder(obj.root);
System.out.println();
obj.root = obj.orderByX(obj.root, 2);
obj.display();
}
}
class Nodes {
private int data;
private Nodes next;
Nodes(int data) {
this.data = data;
this.next = null;
}
public Nodes getNext() {
return next;
}
public void setNext(Nodes next) {
this.next = next;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
I think that maintaining two lists is not an issue. It is possible to use a single list, but at the cost of loosing some of the simplicity.
The principal problem seems to be the addToLinkedList(CustomLinkedList list, int value) method.
It iterates throughout the entire list in order to add a new element.
One alternative is to always add elements at the front of the list. This would also produce a valid solution, and would run faster.
Hi I have this code which will sort a list of strings in order, I can also sort a array into ascending too as there are plenty of tutorials to help me. The problem I have is to sort numbers with letters attached. Is this possible? Here's what I have so far.
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class LinkedList2 {
public static class Node {
public String value;
public Node next;
}
static File dataInpt;
static Scanner inFile;
public static void main(String[] args) throws IOException {
inFile = new Scanner("20\r\n" + "38\r\n" + "5c\r\n" + "2b\r\n" + "54\r\n" + "63\r\n" + "53\r\n" + "43\r\n" + "40\r\n"
+ "14\r\n" + "2a\r\n" + "42\r\n" + "63\r\n" + "63\r\n" + "5c\r\n" + "4c\r\n");
Node first = insertInOrder();
printList(first);
}
public static Node getNode(String element) {
Node temp = new Node();
temp.value = element;
temp.next = null;
return temp;
}
public static void printList(Node head) {
Node ptr; // not pointing anywhere
for (ptr = head; ptr != null; ptr = ptr.next) {
System.out.println(ptr.value);
}
System.out.println();
}
public static Node insertInOrder() {
Node current = getNode(inFile.next());
Node first = current, last = current;
while (inFile.hasNext()) {
if (first != null && current.value.compareTo(first.value) < 0) {
current.next = first;
first = current;
} else if (last != null && current.value.compareTo(last.value) > 0) {
last.next = current;
last = current;
} else {
Node temp = first;
while (current.value.compareTo(temp.value) < 0) {
temp = temp.next;
}
current.next = temp.next;
temp.next = current;
}
current = getNode(inFile.next());
}
return first;
}
}
It is possible to sort any kind of Comparable elements.
If you are using a String as value it will be sorted using the natural order of strings. If you need a different comparison policy you need to write your Comparator and use it to compare the values instead of compare them directly
public static Node insertInOrder(Comparator<String> comparator) {
Node current = getNode(inFile.next());
Node first = current, last = current;
while (inFile.hasNext()) {
if (first != null && comparator.compare(current.value, first.value) < 0) {
current.next = first;
first = current;
} else if (last != null && comparator.compare(current.value, last.value) > 0) {
last.next = current;
last = current;
} else {
Node temp = first;
while (comparator.compare(current.value, temp.value) < 0){
temp = temp.next;
}
current.next = temp.next;
temp.next = current;
}
current = getNode(inFile.next());
}
return first;
}
I think, you need to store an additional data int data item corresponding to String value using below method of Integer class,
public static int parseInt(String s,int radix) throws NumberFormatException
where radix=16. Then you can sort it as normal integer ( base 10 ).
You need to change your Node class to have int in place of String
public static class Node {
public int value;
public Node next;
}
then in your getNode(String element) method , you perform HEX String to int conversion,
public static Node getNode(String element) {
Node temp = new Node();
try{
temp.value = Integer.parseInt(element,16);
}catch(NumberFormatException ex){
ex.printStackTrace();
}
temp.next = null;
return temp;
}
Now you edit your insertInOrder() method to do comparison as simple integers , > , < , == etc instead of value.compareTo
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;