How to sorting list interface - java

I am having problem with sorting patient list based on seriousness and arrival time. Can take a look what wrong with my code? See the LList.java, the SortPatient method is correct?
ListInterface.java
public interface ListInterface<T> {
public boolean add(T newEntry);
public boolean add(int newPosition, T newEntry);
public T remove(int givenPosition);
public void clear();
public boolean replace(int givenPosition, T newEntry);
public T getEntry(int givenPosition);
public boolean contains(T anEntry);
public int getLength();
public boolean isEmpty();
public boolean isFull();
public int getPosition(T anObject);
public void SortPatient(ListInterface<Patient> patientList);
}
Llist.java
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
public class LList<T> implements ListInterface<T> {
private Node firstNode; // reference to first node
private int length; // number of entries in list
public LList() {
clear();
}
public LList(T[] arr) {
clear();
firstNode = new Node(arr[0], null);
Node p = firstNode;
for (int index = 1; index < arr.length; index++) {
p.next = new Node(arr[index], null);
p = p.next;
//index must start with 0
//or add(arr[index]);
}
length = arr.length;
}
public int getPosition(T anObject) {
Node currentNode = firstNode;
int position = 0;
while (currentNode != null) {
position++;
if (currentNode.data.equals(anObject)) {
return position;
}
currentNode = currentNode.next;
}
return -1;
}
public final void clear() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry);
// create the new node
if (isEmpty()) // if empty list
{
firstNode = newNode;
} else { // add to end of nonempty list
Node currentNode = firstNode; // traverse linked list with p pointing to the current node
while (currentNode.next != null) { // while have not reached the last node
currentNode = currentNode.next;
}
currentNode.next = newNode; // make last node reference new node
}
length++;
return true;
}
public boolean add(int newPosition, T newEntry) { // OutOfMemoryError possible
boolean isSuccessful = true;
if ((newPosition >= 1) && (newPosition <= length + 1)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (newPosition == 1)) { // case 1: add to beginning of list
newNode.next = firstNode;
firstNode = newNode;
} else { // case 2: list is not empty and newPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < newPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
newNode.next = nodeBefore.next; // make new node point to current node at newPosition
nodeBefore.next = newNode; // make the node before point to the new node
}
length++;
} else {
isSuccessful = false;
}
return isSuccessful;
}
public T remove(int givenPosition) {
T result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= length)) {
if (givenPosition == 1) { // case 1: remove first entry
result = firstNode.data; // save entry to be removed
firstNode = firstNode.next;
} else { // case 2: givenPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < givenPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
result = nodeBefore.next.data; // save entry to be removed
nodeBefore.next = nodeBefore.next.next; // make node before point to node after the
} // one to be deleted (to disconnect node from chain)
length--;
}
return result; // return removed entry, or
// null if operation fails
}
public boolean replace(int givenPosition, T newEntry) {
boolean isSuccessful = true;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
// System.out.println("Trace| currentNode.data = " + currentNode.data + "\t, i = " + i);
currentNode = currentNode.next; // advance currentNode to next node
}
currentNode.data = newEntry; // currentNode is pointing to the node at givenPosition
} else {
isSuccessful = false;
}
return isSuccessful;
}
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public boolean contains(T anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data)) {
found = true;
} else {
currentNode = currentNode.next;
}
}
return found;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
boolean result;
if (length == 0) {
result = true;
} else {
result = false;
}
return result;
}
public boolean isFull() {
return false;
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data;
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
this.next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // end Node
public void SortPatient(ListInterface<Patient> patientList) {
if (patientList == null) {
return;
}
boolean swapped;
Patient patient;
do {
swapped = false;
patient = head;
while (patientList.next != null) {
if (patient.compareTo(patientList.next) < 1) {
swap(patientList.current, patientList.next);
swapped = true;
}
patient = patientList.next;
}
} while (swapped);
}
}
Patient.java
import java.util.Date;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static javafx.scene.input.KeyCode.T;
public class Patient implements Comparable<Patient> {
String patientId;
String patientName;
String patientGender;
String patientIcNumber;
String patientContactNumber;
Date date;
int seriousness;
static int count = 0;
public Patient() {
}
public Patient(String patientId, String patientName, String patientGender, String patientIcNumber, String patientContactNumber, Date date, int seriousness) {
this.patientId = patientId;
this.patientName = patientName;
this.patientGender = patientGender;
this.patientIcNumber = patientIcNumber;
this.patientContactNumber = patientContactNumber;
this.date = date;
this.seriousness = seriousness;
count++;
}
public String getPatientId() {
return patientId;
}
public void setPatientId(String patientId) {
this.patientId = patientId;
}
public String getPatientName() {
return patientName;
}
public void setPatientName(String patientName) {
this.patientName = patientName;
}
public String getPatientGender() {
return patientGender;
}
public void setPatientGender(String patientGender) {
this.patientGender = patientGender;
}
public String getPatientIcNumber() {
return patientIcNumber;
}
public void setPatientIcNumber(String patientIcNumber) {
this.patientIcNumber = patientIcNumber;
}
public String getPatientContactNumber() {
return patientContactNumber;
}
public void setPatientContactNumber(String patientContactNumber) {
this.patientContactNumber = patientContactNumber;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getSeriousness() {
return seriousness;
}
public void setSeriousness(int seriousness) {
this.seriousness = seriousness;
}
public int getCount() {
return count;
}
#Override
public String toString() {
return patientId + " " + patientName + " " + patientGender + " " + patientIcNumber + " " + patientContactNumber + " " + date + " " + seriousness + "\n";
}
#Override
public int compareTo(Patient t) {
int patientSeriouness = t.seriousness;
Date arrival = t.date;
if (this.seriousness == patientSeriouness) {
return this.date.compareTo(arrival);
} else {
return Integer.compare(this.seriousness, patientSeriouness);
}
}
}

Couple of issues in your code (I just went through add,getentry and sort method):
In getEntry method, Remember index always start with 0 and go after till length - 1, so you should change our method to:
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 0) && (givenPosition < length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
Change your interface and class implementation to remove passing on the ListInterface reference and your implementation should look like:
public void SortPatient() {
if (firstNode == null) {
return;
}
boolean swapped;
Node patient;
do {
swapped = false;
patient = firstNode;
while (patient.next != null) {
if (patient.data.compareTo(patient.next.data) > 0) {
swap(patient, patient.next);
swapped = true;
}
patient = patient.next;
}
} while (swapped);
}
private void swap(Node patient, Node nextPatient) {
T temp = patient.data;
patient.data = nextPatient.data;
nextPatient.data = temp;
}
Your compare to method in Patient class needs some improvements and it should be as below:
#Override
public int compareTo(Patient t) {
int patientSeriouness = t.seriousness;
Date arrival = t.date;
if (this.seriousness == patientSeriouness) {
return this.date.compareTo(arrival);
} else {
return ((Integer)this.seriousness).compareTo(patientSeriouness);
}
}
Last but not the least, your class definition LList should take generics of type Comparable (As you are using compareTo method), so you need to mandate that and it should be defined as
public class LList<T extends Comparable<T>> implements ListInterface<T>

Related

Remove Method for a Single and Double Linked List (Java)

I am struggling to understand how to implement a remove(); for both a double and single linked class. I have figured out how to remove the first node in the double, but not in the single. First I would like to debug, problem solve the single linked class, then work on the double after that.
Here is the code I have so far for the Single Linked Class.
public class SingleLinkedClass<T> {
private Node <T> head;
private Node <T> tail;
private int size;
public SingleLinkedClass() {
size = 0;
head = null;
tail = null;
}
public void insertAtHead(T v)
{
//Allocate new node
Node newNode = new Node(v, head);
//Change head to point to new node
head = newNode;
if(tail == null)
{
tail = head;
}
//Increase size
size++;
}
public void insertAtTail(T v)
{
if(tail == null)
{
tail = new Node(v, null);
head = tail;
size++;
return;
}
Node newNode = new Node(v, null);
tail.nextNode = newNode;
tail = newNode;
size++;
}
public T removeHead()
{
if(head == null)
{
throw new IllegalStateException("list is empty! cannot delete");
}
T value = head.value;
head = head.nextNode;
size--;
return value;
}
public void removeTail()
{
//Case 1: list empty
if(head == null)
{
return;
}
//Case 2: list has one node
else if(head == tail)
{
head = tail = null;
}
else
{
Node temp = head;
while(temp.nextNode != tail)
{
temp = temp.nextNode;
}
tail = temp;
tail.nextNode = null;
}
size--;
}
public boolean remove(T v) {
Node<T> previous = head;
Node<T> cursor = head.nextNode;
if (head.nextNode == null) {
return false;
}
while(cursor != tail){
if (cursor.value.equals(v)) {
previous = cursor.nextNode;
return true;
}
previous = cursor;
cursor = cursor.nextNode;
}
return false;
}
public String toString() {
if (head == null) {
return "The list is Empty!";
}
String result = "";
Node temp = head;
while (temp != null) {
result += temp.toString() + " ";
temp = temp.nextNode;
}
return result;
}
public int size() {
return size;
}
private class Node <T> {
private T value;
private Node <T> nextNode;
public Node(T v, Node<T> n) {
value = v;
nextNode = n;
}
public String toString() {
return "" + value;
}
}
}
Here is my Double Linked Class
public class DoubelyLinkedList<E> {
private int size;
private Node<E> header;
private Node<E> trailer;
public DoubelyLinkedList() {
size = 0;
header = new Node<E>(null, null, null);
trailer = new Node<E>(null, null, header);
header.next = trailer;
}
public boolean remove(E v) {
//If the list is empty return false
if(header.next == trailer){
return false;
}
//If v is the head of the list remove and return true
Node <E> cursor = header.next;
for (int i = 0; i < size; i++) {
//Remove at Head
if(cursor.value.equals(v)){
removeAtHead();
}
cursor = cursor.next;
}
return true;
}
/*
} */
public void insertAtHead(E v) {
insertBetween(v, header, header.next);
}
public void insertAtTail(E v) {
insertBetween(v, trailer.prev, trailer);
}
private void insertBetween(E v, Node<E> first, Node<E> second) {
Node<E> newNode = new Node<>(v, second, first);
first.next = newNode;
second.prev = newNode;
size++;
}
public E removeAtHead() {
return removeBetween(header, header.next.next);
}
public E removeAtTail() {
return removeBetween(trailer.prev.prev, trailer);
}
private E removeBetween(Node<E> first, Node<E> second) {
if (header.next == trailer)// if the list is empty
{
throw new IllegalStateException("The list is empty!");
}
E result = first.next.value;
first.next = second;
second.prev = first;
size--;
return result;
}
public String toStringBackward() {
if (size == 0) {
return "The list is empty!";
}
String r = "";
Node<E> temp = trailer.prev;
while (temp != header) {
r += temp.toString() + " ";
temp = temp.prev;
}
return r;
}
public String toString() {
if (size == 0) {
return "The list is empty!";
}
String r = "";
Node<E> temp = header.next;
while (temp != trailer) {
r += temp + " ";
temp = temp.next;
}
return r;
}
private static class Node<T> {
private T value;
private Node<T> next;
private Node<T> prev;
public Node(T v, Node<T> n, Node<T> p) {
value = v;
next = n;
prev = p;
}
public String toString() {
return value.toString();
}
}
}
Here is my Driver
public class Driver {
public static void main(String[] args) {
DoubelyLinkedList<String> doubley = new DoubelyLinkedList();
SingleLinkedClass<String> single = new SingleLinkedClass();
single.insertAtHead("Bob");
single.insertAtHead("Sam");
single.insertAtHead("Terry");
single.insertAtHead("Don");
System.out.println(single);
single.remove("Bob");
System.out.println("Single Remove Head: " + single);
/*
single.remove("Don");
System.out.println("Single Remove Tail: " + single);
single.remove("Terry");
System.out.println("Single Remove Inbetween: " + single);
*/
System.out.println();
System.out.println();
doubley.insertAtHead("Bob");
doubley.insertAtHead("Sam");
doubley.insertAtHead("Terry");
doubley.insertAtHead("Don");
System.out.println(doubley);
doubley.remove("Bob");
System.out.println("Double Remove Head: " + doubley);
doubley.remove("Don");
System.out.println("Double Remove Tail: " + doubley);
/*
doubley.remove("Sam");
System.out.println("Double Remove Inbetween: " + doubley);
*/
}
}
In the removeHead moving head to its next, it might become null. Then tail was the head too. Then tail should be set to null too.
DoublyLinkedList is better English than DoubelyLinkedList.
As this is homework, I leave it by this.

Implement multiset using sorted linkedList

Hello I implemented a multiset using a linkedlist and I want to implement the multiset using sorted linkedlist. This is multiset abstract class.
import java.io.PrintStream;
public abstract class Multiset<T> {
/**
* Delimiter string for print operation.
*/
protected static final String printDelim = " | ";
public abstract void add(T item);
public abstract int search(T item);
public abstract void removeOne(T item);
public abstract void removeAll(T item);
public abstract void print(PrintStream out);
}
This is my implementation of linkedlist.
import java.io.PrintStream;
public class LinkedListMultiset<T> extends Multiset<T> {
protected Node mHead;
protected int mLength;
public LinkedListMultiset() {
// Implement me!
mHead = null;
mLength = 0;
}
public void add(T item) {
Node newNode = new Node((String) item);
if (mHead == null)
mHead = newNode;
else {
Node currNode = mHead;
Node parentNode = null;
while (currNode != null) {
if (currNode.getValue().
equals(newNode.getValue())) {
currNode.addCounter();
return;
}
parentNode = currNode;
currNode = currNode.getNext();
}
parentNode.setNext(newNode);
}
mLength++;
}
public int search(T item) {
Node currNode = mHead;
while (currNode != null) {
if (currNode.getValue().equals((String) item)) {
return currNode.getCounter();
}
currNode = currNode.getNext();
}
return 0;
}
public void removeOne(T item) {
Node currNode = mHead;
Node lastNode = null;
while (currNode != null) {
if (currNode.getValue().equals((String) item)) {
currNode.minusCounter();
if (currNode.getCounter() == 0) {
if (currNode == mHead)
mHead = currNode.getNext();
else
lastNode.setNext
(currNode.getNext());
mLength--;
}
return;
}
lastNode = currNode;
currNode = currNode.getNext();
}
}
public void removeAll(T item) {
Node currNode = mHead;
Node lastNode = null;
while (currNode != null) {
if (currNode.getValue().equals((String) item)) {
if (currNode == mHead)
mHead = currNode.getNext();
else
lastNode.setNext(currNode.getNext());
mLength--;
return;
}
lastNode = currNode;
currNode = currNode.getNext();
}
}
public void print(PrintStream out) {
Node currNode = mHead;
while (currNode != null) {
out.printf("%s | %d\n", currNode.getValue()
, currNode.getCounter());
currNode = currNode.getNext();
}
}
private class Node {
protected String mValue;
protected Node mNext;
int counter;
public Node(String value) {
mValue = value;
mNext = null;
counter = 1;
}
public void addCounter() {
counter++;
}
public void minusCounter() {
counter--;
}
public int getCounter() {
return counter;
}
public String getValue() {
return mValue;
}
public Node getNext() {
return mNext;
}
public void setValue(String value) {
mValue = value;
}
public void setNext(Node next) {
mNext = next;
}
}
}
I want to implement sorted linkedlist but I want to change my code as minimum as possible.

how to make an .add method which adding objects in a reference based list in alphabetically order

This is my user class and i found that i have to use the compareTo method but i need a method which adding in a Rb list.
There is an already existed add method and i have make a similar which order the users alphabetically.
import java.lang.Comparable;
public class LaptopUser implements Comparable<LaptopUser>
{
private String username;
private String password;
public LaptopUser(String username,String password)
{
this.username=username;
this.password=password;
}
public String getUsername(){
return username ;
}
public String getPass()
{
return password;
}
public String toString(){
return(username+","+password);
}
#Override
public int compareTo(LaptopUser n)
{
if(this.toString().compareTo(n.toString())>0)
{
return 1;
}
else if(this.toString().compareTo(n.toString())<0)
{
return -1;
}
return 0;
}
public boolean equals(LaptopUser p)
{
return(this.toString().equals(p.toString()));
}
}
public class ReferenceBasedList implements ListInterface
{
private ListNode head;
private ListNode tail;
int numItems;
public ReferenceBasedList()
{
head = tail = null;
numItems = 0;
}
public int size()
{
return numItems;
}
public boolean isEmpty()
{
return (numItems == 0);
}
public void removeAll()
{
head = tail = null;
numItems = 0;
}
private ListNode find(int index)
{
ListNode curr = head;
for (int skip = 1; skip < index; skip++)
curr = curr.getNext();
return curr;
}
public Object get(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 1 && index <= numItems)
{
ListNode curr = find(index);
return curr.getItem();
}
else
{
throw new ListIndexOutOfBoundsException(
"List index out of bounds exception on get");
}
}
public void add(int index, Object newDataItem)
throws ListIndexOutOfBoundsException
{
if (index >= 1 && index <= numItems+1)
{
if ( index == 1 )
{
ListNode newNode = new ListNode(newDataItem, head);
head = newNode;
if (tail==null)
tail = head;
}
else if ( index==numItems+1 )
{
ListNode newNode = new ListNode(newDataItem);
tail.setNext(newNode);
tail = newNode;
}
else
{
ListNode prev = find(index-1);
ListNode newNode = new ListNode(newDataItem, prev.getNext());
prev.setNext(newNode);
}
numItems++;
}
else
{
throw new ListIndexOutOfBoundsException(
"List index out of bounds exception on add");
}
}
public void insert(Object newDataItem)
{
this.add(1,newDataItem);
}
public void append(Object newDataItem)
{
this.add(numItems+1,newDataItem);
}
public Object showFront()
{
return this.get(1);
}
public Object showLast()
{
return this.get(numItems);
}
public void remove(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 1 && index <= numItems)
{
if (index == 1)
{
head = head.getNext();
if (head == null)
tail = null;
}
else
{
ListNode prev = find(index-1);
ListNode curr = prev.getNext();
prev.setNext(curr.getNext());
if (index == numItems)
tail = prev;
}
numItems--;
}
else
{
throw new ListIndexOutOfBoundsException(
"List index out of bounds exception on remove");
}
}
public boolean exists(Object dataItem)
{
for (ListNode tmp=head; tmp!=null; tmp=tmp.getNext())
if (tmp.getItem().equals(dataItem))
return true;
return false;
}
public Object removeLast() throws ListException
{
if (isEmpty())
throw new ListException("The linked list is empty");
else
{
Object lastDataItem = tail.getItem();
if (head == tail)
head = tail = null;
else
{
ListNode tmp = head;
while (tmp.getNext().getNext() != null)
tmp = tmp.getNext();
tail = tmp;
tail.setNext(null);
}
numItems--;
return lastDataItem;
}
}
public Object removeFront() throws ListException
{
if (isEmpty())
throw new ListException("The linked list is empty");
else
{
Object frontDataItem = head.getItem();
head = head.getNext();
if (head == null)
tail = null;
numItems--;
return frontDataItem;
}
}
}
You can use the Collections.binarySearch method to find at what index a LaptopUser should be added to a List in order for it to be alphabetically ordered.
SortedList:
public class SortedList implements Iterable<LaptopUser> {
public List<LaptopUser> users = new ArrayList<LaptopUser>();
public void add(LaptopUser user) {
int index = Collections.binarySearch(users, user);
if (index < 0)
users.add(-index - 1, user);
else
users.add(index, user);
}
#Override
public Iterator<LaptopUser> iterator() {
return users.iterator();
}
Example Code:
public class LaptopUser implements Comparable<LaptopUser> {
public String username;
public String password;
public LaptopUser(String username, String password) {
this.username = username;
this.password = password;
}
#Override
public int compareTo(LaptopUser o) {
return toString().compareTo(o.toString());
}
#Override
public String toString() {
return username.concat(password);
}
}
public Sorted() {
LaptopUser a =new LaptopUser("a", "password");
LaptopUser b =new LaptopUser("b", "password");
LaptopUser c =new LaptopUser("c", "password");
SortedList list = new SortedList();
list.add(c);
list.add(a);
list.add(b);
for(LaptopUser user : list)
System.out.println(user);
}
public static void main(String[] args) {
new Sorted();
}
Output:
apassword
bpassword
cpassword

Removing Item at index from a linked list?

public class LinkedList
{
private Node head;
private Node tail;
private int numberOfElements;
public LinkedList()
{
head = null;
tail = null;
this.numberOfElements = 0;
}
public int length()
{
return this.numberOfElements;
}
public void removeFront()
{
Node currNode = head;
head = head.getNextNode();
currNode.setNextNode(null);
this.numberOfElements--;
}
public void removeLast()
{
this.tail = this.tail.prev;
}
public void removeAtIndex(int index) throws AmishException
{
if (index == 0) {
Node q = head;
head = q.getNextNode();
}
else if ((index > numberOfElements - 1) || (index < 0))
System.out.println("Index out bounds.");
else {
Node currNode = head;
for (int i = 0; i < index; i++) {
currNode = currNode.getNextNode();
}
Node temp = currNode;
currNode = temp.getPrevNode();
currNode.setNextNode(temp.getNextNode());
temp = null;
numberOfElements--;
}
}
Node -
public class Node
{
private int payload;
private Node nextNode;
public Node prev;
public Node previous;
public Node next;
public Node(int payload)
{
this.payload = payload;
nextNode = null;
}
public Node getNextNode()
{
return this.nextNode;
}
public Node getPrevNode()
{
return this.getPrevNode();
}
public void setNextNode(Node n)
{
this.nextNode = n;
}
public void display()
{
System.out.print("(" + super.toString() + " : " + this.payload + ")");
if(this.nextNode != null)
{
System.out.print(" -> ");
this.nextNode.display();
}
else
{
System.out.println("");
}
}
public String toString()
{
return "" + super.toString() + " : " + this.payload;
}
public void setPrevNode(Node n)
{
previous = n;
}
}
Driver -
public class Driver
{
public static void main(String[] args) throws Exception
{
LinkedList ll = new LinkedList();
ll.addFront(7);
ll.addFront(5);
ll.addEnd(13);
ll.addEnd(27);
ll.addFront(2);
ll.addAtIndex(1, 0);
ll.addAtIndex(12, 6);
ll.addAtIndex(9, 2);
ll.addAtIndex(11, 2);
//ll.removeFront();
//ll.removeLast();
ll.removeAtIndex(1);
for(int i = 0; i < ll.length(); i++)
{
System.out.println(ll.get(i));
}
}
}
I got what I need to remove the head's index, but how to do anything else is beyond me.
I have the methods to remove the head and the tail now I just need to know how to remove at an index just Like if I were to add at an index.
Okay, completely editing this answer. I took your code and went from that. There were some issues with your Node class, check out mine. I created a barebones Node class, add the any other functionality you may need/want. For the LinkedList class, I created a simple add method that adds to the end of the list. Use this as a prototype for your other adds. Everything right now is working and I put some println's to help you see where the program is at. I highly recommend using a debugger. Also note that this is a doubly linked list.
Linked List
public class LinkedList {
private Node head;
private Node tail;
private int numberOfElements;
public LinkedList()
{
head = null;
tail = null;
numberOfElements = 0;
}
public int length()
{
return numberOfElements;
}
public void removeAtIndex(int index)
{
if (index == 0) {
Node q = head;
head = q.getNextNode();
numberOfElements--;
}
else if ((index > numberOfElements - 1) || (index < 0))
System.out.println("Index out of bounds.");
else {
Node currNode = head;
for (int i = 0; i < index; i++) {
//Node p = currNode;
System.out.println("At this payload " + currNode.getPayload());
currNode = currNode.getNextNode();
System.out.println("Now at this payload " + currNode.getPayload());
}
Node temp = currNode;
System.out.println("Removing the node with payload " + temp.getPayload());
currNode = temp.getPrevNode();
currNode.setNextNode(temp.getNextNode());
temp = null;
numberOfElements--;
}
}
public void add(int num) {
Node newNode = new Node(num);
newNode.setNextNode(null);
if (numberOfElements == 0) {
newNode.setPrevNode(null);
head = newNode;
tail = newNode;
}
else if (numberOfElements == 1) {
head.setNextNode(newNode);
tail = newNode;
tail.setPrevNode(head);
}
else {
newNode.setPrevNode(tail);
tail.setNextNode(newNode);
tail = newNode;
}
System.out.println("Inserted " + num + " into the linked list");
numberOfElements++;
}
public void printList() {
Node temp = head;
while (temp != null) {
System.out.println("Node with payload " + temp.getPayload());
temp = temp.getNextNode();
}
}
}
Node
public class Node {
private int payload;
private Node next;
private Node prev;
public Node(int payload) {
this.payload = payload;
prev = null;
next = null;
}
public Node getNextNode() {
return next;
}
public Node getPrevNode() {
return prev;
}
public void setNextNode(Node n) {
next = n;
}
public void setPrevNode(Node n) {
prev = n;
}
public int getPayload() {
return payload;
}
}
Driver
public class Driver {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add(7);
ll.add(5);
ll.add(13);
ll.add(27);
ll.add(2);
ll.printList();
ll.removeAtIndex(3);
ll.printList();
}
}

Does java have a skip list implementation

I find ConcurrentSkipListSet in Java Collection Framework, which is backed up with a skip list. But is there a skip list in Java? A set does not work in my use case. I need a indexable list that supports duplicates.
This answer is 3 years late but I hope it will be useful for those wanting a Java skip list from this moment on :)
This solution allows duplicates as you asked. I follow roughly the guide here http://igoro.com/archive/skip-lists-are-fascinating, so the complexities are similar to that, except delete costs O(nlogn) - as I didn't bother using doubly-linked nodes, I imagine doing so would bring delete down to O(logn).
Code comprises of: an interface, the skip list implementing the interface, and the node class. It is also generic.
You can tune the parameter LEVELS for performance, but remember the space-time tradeoff.
import java.util.Random;
interface SkippableList<T extends Comparable<? super T>> {
int LEVELS = 5;
boolean delete(T target);
void print();
void insert(T data);
SkipNode<T> search(T data);
}
public class SkipList<T extends Comparable<? super T>> implements SkippableList<T> {
public static void main(String[] args) {
SkipList<Integer> sl = new SkipList<>();
int[] data = {4,2,7,0,9,1,3,7,3,4,5,6,0,2,8};
for (int i : data) {
sl.insert(i);
}
sl.print();
sl.search(4);
sl.delete(9);
sl.print();
sl.insert(69);
sl.print();
sl.search(69);
}
private final SkipNode<T> head = new SkipNode<>(null);
private final Random rand = new Random();
#Override
public void insert(T data) {
SkipNode<T> SkipNode = new SkipNode<>(data);
for (int i = 0; i < LEVELS; i++) {
if (rand.nextInt((int) Math.pow(2, i)) == 0) { //insert with prob = 1/(2^i)
insert(SkipNode, i);
}
}
}
#Override
public boolean delete(T target) {
System.out.println("Deleting " + target.toString());
SkipNode<T> victim = search(target, false);
if (victim == null) return false;
victim.data = null;
for (int i = 0; i < LEVELS; i++) {
head.refreshAfterDelete(i);
}
System.out.println();
return true;
}
#Override
public SkipNode<T> search(T data) {
return search(data, true);
}
#Override
public void print() {
for (int i = 0; i < LEVELS; i++) {
head.print(i);
}
System.out.println();
}
private void insert(SkipNode<T> SkipNode, int level) {
head.insert(SkipNode, level);
}
private SkipNode<T> search(T data, boolean print) {
SkipNode<T> result = null;
for (int i = LEVELS-1; i >= 0; i--) {
if ((result = head.search(data, i, print)) != null) {
if (print) {
System.out.println("Found " + data.toString() + " at level " + i + ", so stoppped" );
System.out.println();
}
break;
}
}
return result;
}
}
class SkipNode<N extends Comparable<? super N>> {
N data;
#SuppressWarnings("unchecked")
SkipNode<N>[] next = (SkipNode<N>[]) new SkipNode[SkippableList.LEVELS];
SkipNode(N data) {
this.data = data;
}
void refreshAfterDelete(int level) {
SkipNode<N> current = this.getNext(level);
while (current != null && current.getNext(level) != null) {
if (current.getNext(level).data == null) {
SkipNode<N> successor = current.getNext(level).getNext(level);
current.setNext(successor, level);
return;
}
current = current.getNext(level);
}
}
void setNext(SkipNode<N> next, int level) {
this.next[level] = next;
}
SkipNode<N> getNext(int level) {
return this.next[level];
}
SkipNode<N> search(N data, int level, boolean print) {
if (print) {
System.out.print("Searching for: " + data + " at ");
print(level);
}
SkipNode<N> result = null;
SkipNode<N> current = this.getNext(level);
while (current != null && current.data.compareTo(data) < 1) {
if (current.data.equals(data)) {
result = current;
break;
}
current = current.getNext(level);
}
return result;
}
void insert(SkipNode<N> SkipNode, int level) {
SkipNode<N> current = this.getNext(level);
if (current == null) {
this.setNext(SkipNode, level);
return;
}
if (SkipNode.data.compareTo(current.data) < 1) {
this.setNext(SkipNode, level);
SkipNode.setNext(current, level);
return;
}
while (current.getNext(level) != null && current.data.compareTo(SkipNode.data) < 1 &&
current.getNext(level).data.compareTo(SkipNode.data) < 1) {
current = current.getNext(level);
}
SkipNode<N> successor = current.getNext(level);
current.setNext(SkipNode, level);
SkipNode.setNext(successor, level);
}
void print(int level) {
System.out.print("level " + level + ": [");
int length = 0;
SkipNode<N> current = this.getNext(level);
while (current != null) {
length++;
System.out.print(current.data.toString() + " ");
current = current.getNext(level);
}
System.out.println("], length: " + length);
}
}
Fixed the bug in the implementation provided by #PoweredByRice. It threw an NPE for cases when the node deleted was the first node. Other updates include renamed variable names and reverse printing the order of the skip list.
import java.util.Random;
interface SkippableList<T extends Comparable<? super T>> {
int LEVELS = 5;
boolean delete(T target);
void print();
void insert(T data);
SkipNode<T> search(T data);
}
class SkipNode<N extends Comparable<? super N>> {
N data;
#SuppressWarnings("unchecked")
SkipNode<N>[] next = (SkipNode<N>[]) new SkipNode[SkippableList.LEVELS];
SkipNode(N data) {
this.data = data;
}
void refreshAfterDelete(int level) {
SkipNode<N> current = this;
while (current != null && current.getNext(level) != null) {
if (current.getNext(level).data == null) {
SkipNode<N> successor = current.getNext(level).getNext(level);
current.setNext(successor, level);
return;
}
current = current.getNext(level);
}
}
void setNext(SkipNode<N> next, int level) {
this.next[level] = next;
}
SkipNode<N> getNext(int level) {
return this.next[level];
}
SkipNode<N> search(N data, int level, boolean print) {
if (print) {
System.out.print("Searching for: " + data + " at ");
print(level);
}
SkipNode<N> result = null;
SkipNode<N> current = this.getNext(level);
while (current != null && current.data.compareTo(data) < 1) {
if (current.data.equals(data)) {
result = current;
break;
}
current = current.getNext(level);
}
return result;
}
void insert(SkipNode<N> skipNode, int level) {
SkipNode<N> current = this.getNext(level);
if (current == null) {
this.setNext(skipNode, level);
return;
}
if (skipNode.data.compareTo(current.data) < 1) {
this.setNext(skipNode, level);
skipNode.setNext(current, level);
return;
}
while (current.getNext(level) != null && current.data.compareTo(skipNode.data) < 1 &&
current.getNext(level).data.compareTo(skipNode.data) < 1) {
current = current.getNext(level);
}
SkipNode<N> successor = current.getNext(level);
current.setNext(skipNode, level);
skipNode.setNext(successor, level);
}
void print(int level) {
System.out.print("level " + level + ": [ ");
int length = 0;
SkipNode<N> current = this.getNext(level);
while (current != null) {
length++;
System.out.print(current.data + " ");
current = current.getNext(level);
}
System.out.println("], length: " + length);
}
}
public class SkipList<T extends Comparable<? super T>> implements SkippableList<T> {
private final SkipNode<T> head = new SkipNode<>(null);
private final Random rand = new Random();
#Override
public void insert(T data) {
SkipNode<T> skipNode = new SkipNode<>(data);
for (int i = 0; i < LEVELS; i++) {
if (rand.nextInt((int) Math.pow(2, i)) == 0) {
//insert with prob = 1/(2^i)
insert(skipNode, i);
}
}
}
#Override
public boolean delete(T target) {
System.out.println("Deleting " + target);
SkipNode<T> victim = search(target, true);
if (victim == null) return false;
victim.data = null;
for (int i = 0; i < LEVELS; i++) {
head.refreshAfterDelete(i);
}
System.out.println("deleted...");
return true;
}
#Override
public SkipNode<T> search(T data) {
return search(data, true);
}
#Override
public void print() {
for (int i = LEVELS-1; i >= 0 ; i--) {
head.print(i);
}
System.out.println();
}
private void insert(SkipNode<T> SkipNode, int level) {
head.insert(SkipNode, level);
}
private SkipNode<T> search(T data, boolean print) {
SkipNode<T> result = null;
for (int i = LEVELS-1; i >= 0; i--) {
if ((result = head.search(data, i, print)) != null) {
if (print) {
System.out.println("Found " + data.toString() + " at level " + i + ", so stopped" );
System.out.println();
}
break;
}
}
return result;
}
public static void main(String[] args) {
SkipList<Integer> sl = new SkipList<>();
int[] data = {4,2,7,0,9,1,3,7,3,4,5,6,0,2,8};
for (int i : data) {
sl.insert(i);
}
sl.print();
sl.search(4);
sl.delete(4);
System.out.println("Inserting 10");
sl.insert(10);
sl.print();
sl.search(10);
}
}
Since you've mentioned a List that is both Indexable (I assume you want speedy retrieval) and need to allow duplicates, I would advise you go for a custom Set with a LinkedList or ArrayList perhaps.
You need to have a base Set, an HashSet for example and keep adding values to it. If you face a duplicate, the value of that Set should point to a List. So, that you will have both Speedy retrieval and of course you will store your objects in a psuedo Collection manner.
This should give you good efficiency for retrieval. Ideally if your Keys are not duplicates, you will achieve an O(1) as the retrieval speed.
When you create a ConcurrentSkipListSet, you pass a comparator to the constructor.
new ConcurrentSkipListSet<>(new ExampleComparator());
public class ExampleComparator implements Comparator<Event> {//your impl }
You could create a comparator that will make your SkipListSet behave as a normal List.
You can make use the below to code make your own basic skiplist :
1)Make start and end to represent start and end of skip list.
2)Add the nodes and assign pointers to next based on
if(node is even)
then ,assign a fast lane pointer with next pointer
else
assign only pointer to next node
Java code for basic skip list (you can add more features if you want):
public class MyClass {
public static void main(String args[]) {
Skiplist skiplist=new Skiplist();
Node n1=new Node();
Node n2=new Node();
Node n3=new Node();
Node n4=new Node();
Node n5=new Node();
Node n6=new Node();
n1.setData(1);
n2.setData(2);
n3.setData(3);
n4.setData(4);
n5.setData(5);
n6.setData(6);
skiplist.insert(n1);
skiplist.insert(n2);
skiplist.insert(n3);
skiplist.insert(n4);
skiplist.insert(n5);
skiplist.insert(n6);
/*print all nodes*/
skiplist.display();
System.out.println();
/* print only fast lane node*/
skiplist.displayFast();
}
}
class Node{
private int data;
private Node one_next; //contain pointer to next node
private Node two_next; //pointer to node after the very next node
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getOne_next() {
return one_next;
}
public void setOne_next(Node one_next) {
this.one_next = one_next;
}
public Node getTwo_next() {
return two_next;
}
public void setTwo_next(Node two_next) {
this.two_next = two_next;
}
}
class Skiplist{
Node start; //start pointer to skip list
Node head;
Node temp_next; //pointer to store last used fast lane node
Node end; //end of skip list
int length;
public Skiplist(){
start=new Node();
end=new Node();
length=0;
temp_next=start;
}
public void insert(Node node){
/*if skip list is empty */
if(length==0){
start.setOne_next(node);
node.setOne_next(end);
temp_next.setTwo_next(end);
head=start;
length++;
}
else{
length++;
Node temp=start.getOne_next();
Node prev=start;
while(temp != end){
prev=temp;
temp=temp.getOne_next();
}
/*add a fast lane pointer for even no of nodes*/
if(length%2==0){
prev.setOne_next(node);
node.setOne_next(end);
temp_next.setTwo_next(node);
temp_next=node;
node.setTwo_next(end);
}
/*odd no of node will not contain fast lane pointer*/
else{
prev.setOne_next(node);
node.setOne_next(end);
}
}
}
public void display(){
System.out.println("--Simple Traversal--");
Node temp=start.getOne_next();
while(temp != end){
System.out.print(temp.getData()+"=>");
temp=temp.getOne_next();
}
}
public void displayFast(){
System.out.println("--Fast Lane Traversal--");
Node temp=start.getTwo_next();
while(temp !=end){
System.out.print(temp.getData()+"==>");
temp=temp.getTwo_next();
}
}
}
Output:
--Simple Traversal--
1=>2=>3=>4=>5=>6=>
--Fast Lane Traversal--
2==>4==>6==>
I approve to use TreeList from apache-collections and decorate it with SortedList from Happy Java Libraries
https://sourceforge.net/p/happy-guys/wiki/Sorted%20List/
I am not claiming that this is my own implementation. I just cannot remember where I found it. If you know let me know and I will update. This has been working quite well for me:
public class SkipList<T extends Comparable<? super T>> implements Iterable<T> {
Node<T> _head = new Node<>(null, 33);
private final Random rand = new Random();
private int _levels = 1;
private AtomicInteger size = new AtomicInteger(0);
/// <summary>
/// Inserts a value into the skip list.
/// </summary>
public void insert(T value) {
// Determine the level of the new node. Generate a random number R. The
// number of
// 1-bits before we encounter the first 0-bit is the level of the node.
// Since R is
// 32-bit, the level can be at most 32.
int level = 0;
size.incrementAndGet();
for (int R = rand.nextInt(); (R & 1) == 1; R >>= 1) {
level++;
if (level == _levels) {
_levels++;
break;
}
}
// Insert this node into the skip list
Node<T> newNode = new Node<>(value, level + 1);
Node<T> cur = _head;
for (int i = _levels - 1; i >= 0; i--) {
for (; cur.next[i] != null; cur = cur.next[i]) {
if (cur.next[i].getValue().compareTo(value) > 0)
break;
}
if (i <= level) {
newNode.next[i] = cur.next[i];
cur.next[i] = newNode;
}
}
}
/// <summary>
/// Returns whether a particular value already exists in the skip list
/// </summary>
public boolean contains(T value) {
Node<T> cur = _head;
for (int i = _levels - 1; i >= 0; i--) {
for (; cur.next[i] != null; cur = cur.next[i]) {
if (cur.next[i].getValue().compareTo(value) > 0)
break;
if (cur.next[i].getValue().compareTo(value) == 0)
return true;
}
}
return false;
}
/// <summary>
/// Attempts to remove one occurence of a particular value from the skip
/// list. Returns
/// whether the value was found in the skip list.
/// </summary>
public boolean remove(T value) {
Node<T> cur = _head;
boolean found = false;
for (int i = _levels - 1; i >= 0; i--) {
for (; cur.next[i] != null; cur = cur.next[i]) {
if (cur.next[i].getValue().compareTo(value) == 0) {
found = true;
cur.next[i] = cur.next[i].next[i];
break;
}
if (cur.next[i].getValue().compareTo(value) > 0)
break;
}
}
if (found)
size.decrementAndGet();
return found;
}
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
public Iterator<T> iterator() {
return new SkipListIterator(this, 0);
}
public int size() {
return size.get();
}
public Double[] toArray() {
Double[] a = new Double[size.get()];
int i = 0;
for (T t : this) {
a[i] = (Double) t;
i++;
}
return a;
}
}
class Node<N extends Comparable<? super N>> {
public Node<N>[] next;
public N value;
#SuppressWarnings("unchecked")
public Node(N value, int level) {
this.value = value;
next = new Node[level];
}
public N getValue() {
return value;
}
public Node<N>[] getNext() {
return next;
}
public Node<N> getNext(int level) {
return next[level];
}
public void setNext(Node<N>[] next) {
this.next = next;
}
}
class SkipListIterator<E extends Comparable<E>> implements Iterator<E> {
SkipList<E> list;
Node<E> current;
int level;
public SkipListIterator(SkipList<E> list, int level) {
this.list = list;
this.current = list._head;
this.level = level;
}
public boolean hasNext() {
return current.getNext(level) != null;
}
public E next() {
current = current.getNext(level);
return current.getValue();
}
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
}

Categories