Given a comperator which compares objects of some type T, How can I sort my linked list based on this comparison?
Here's the code for the class Link of my linked list:
public class Link<T> {
private T data;
private Link<T> next;
public Link(T data, Link<T> next){
this.data = data;
this.next = next;
}
public Link(T data){
this(data, null);
}
public T getData(){
return data;
}
public Link<T> getNext(){
return next;
}
public void setNext(Link<T> next){
this.next = next;
}
public T setData(T data){
T tmp = this.data;
this.data = data;
return tmp;
}
public boolean equals(Object other) {
if(!(other instanceof Link<?>))
return false;
T otherData = ((Link<T>) other).data;
return data.equals(otherData);
}
public String toString(){
return data.toString();
}
And here is the class of the LinkedList:
import java.util.Iterator;
public class LinkedList<T> implements List<T> {
private Link<T> first;
private Link<T> last;
public LinkedList(){
first = null;
last = null;
}
public void sortBy(Comparator<T> comp){
// Thats what Im trying to fill
}
public String toString() {
String output = "[";
for (Link<T> curr = first; curr!=null; curr=curr.getNext())
output = output+curr.toString() + ", ";
output = output+"]";
return output;
}
public boolean equals(Object other) {
if (!(other instanceof LinkedList<?>))
return false;
LinkedList<T> otherList = (LinkedList<T>) other;
if (size()!= otherList.size())
return false;
Iterator<T> IterA = iterator();
Iterator<T> IterB = otherList.iterator();
while (IterA.hasNext()) {
if (!(IterA.next()).equals(IterB.next()))
return false;
}
return true;
}
public void add(int index, T element) {
rangeCheck(index);
nullCheck(element);
if(index == 0) {
first = new Link<T>(element, first) ;
if(last == null)
last = first ;
} else {
Link<T> prev = null ;
Link<T> curr = first ;
for(int i=0; i<index; i=i+1) {
prev = curr ;
curr = curr.getNext() ;
}
Link<T> toAdd = new Link<T>(element, curr);
prev.setNext(toAdd);
if(index == size())
last = toAdd;
}
}
public void add(T element) {
nullCheck(element);
if(isEmpty()){
first = new Link<T>(element);
last = first;
}
else {
Link<T> newLast = new Link<T>(element);
last.setNext(newLast);
last = newLast;
}
}
@Override
public int size() {
int counter = 0;
for (Link<T> curr=first; curr!=null; curr=curr.getNext())
counter++;
return counter;
}
@Override
public boolean contains(T element) {
for (Link<T> curr = first; curr!=null; curr=curr.getNext() )
if ((curr.getData()).equals(element))
return true;
return false;
}
@Override
public boolean isEmpty() {
if (first == null)
return true;
return false;
}
@Override
public T get(int index) {
rangeCheck(index);
Link<T> curr = first;
for (int i=index; i>0; i=i-1)
curr=curr.getNext();
return curr.getData();
}
@Override
public T set(int index, T element) {
rangeCheck(index);
Link<T> curr = first;
for (int i=index; i>0; i=i-1)
curr=curr.getNext();
T tmp = curr.getData();
curr.setData(element);
return tmp;
}
@Override
public Iterator<T> iterator() {
return new LinkedListIterator<T>(first);
}
// throws an exception if the given index is not in range
private void rangeCheck(int index) {
if(index < 0 || index >= size())
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size());
}
// throws an exception if the given element is null
private void nullCheck(Object element){
if (element == null)
throw new NullPointerException();
}
}
Is there efficient way to sort the linked list without Collections, and using only the methods in the class LinkedList ? (without creating new arrays or new Links)
What I tried to do is using while and for loops with the functions "get(int index)" and "set(int index)"
But Im looking for more efficient way.
Thanks in advance.
Collectionsutility class. Explain your reluctance to useCollections.