I've created a sorted linked list class, and the only part I'm struggling with is implementing the toArray() method properly.
public class SortedLinkedList<T extends Comparable<T>> implements ListInterface<T>
{
// container class
private class LinkedNode<T>
{
public T data;
public LinkedNode<T> next;
public LinkedNode(T data, LinkedNode<T> next)
{
this.data = data;
this.next = next;
}
}
// private variables
private LinkedNode<T> head, tail;
private int size;
private String name;
// constructor
public SortedLinkedList(String name)
{
head = null;
tail = null;
size = 0;
this.name = name;
}
// core functions
public void Add(T data)
{
size++;
// creation of new node to be added
LinkedNode<T> newNode = new LinkedNode<T>(data, null);
// check for empty list; adds node at head if so
if (head == null)
{
head = newNode;
return;
}
if (head.data.compareTo(data) < 0)
{
head = newNode;
return;
}
// insertion in middle
LinkedNode<T> current = head;
LinkedNode<T> prev = null;
while (current != null)
{
if (current.data.compareTo(data) > 0)
{
prev.next = newNode;
newNode.next = current;
return;
}
prev = current;
current = current.next;
}
// insertion at end
prev.next = newNode;
return;
}
public void Remove(T data)
{
if (head == null)
{
return;
}
LinkedNode<T> current = head.next;
while (current != null && current.next != null)
{
if (current.data.compareTo(current.next.data) == 0)
{
current.next = current.next.next;
} else {
current = current.next;
}
}
size--;
}
public int size()
{
return size;
}
#SuppressWarnings("unchecked")
public T[] toArray()
{
T[] result = (T[])(new Comparable[size()]);
int counter = 0;
for ( T item : )
{
result[counter++] = item;
}
return result;
}
The problem I'm having is what I should include after "T item : " in my for/each line. I had no problem with implementing a similar toArray() method in a set class recently, as that was "for each item in the set", but for some reason I'm blanking on what to place there for the linked list.
Try this.
#SuppressWarnings("unchecked")
public T[] toArray()
{
T[] result = (T[])(new Comparable[size()]);
int counter = 0;
for ( LinkedNode<T> cursor = head; cursor != null; cursor = cursor.next )
{
result[counter++] = cursor.data;
}
return result;
}
Actually, the answer to your question is this:
#SuppressWarnings("unchecked")
public T[] toArray() {
T[] result = (T[])(new Comparable[size()]);
int counter = 0;
for (T item : this) {
result[counter++] = item;
}
return result;
}
This is correct, but to do this you have to implement Iterable<T> interface:
public class SortedLinkedList<T extends Comparable<T>> implements ListInterface<T>, Iterable<T> {
#Override
public Iterator<T> iterator() {
return null;
}
// ...
}
Don't use for loop with linked-lists. Try something like below:
LinkedNode cursor = head;
int index = 0;
while (cursor != null ){
result[index] = cursor.data;
cursor = cursor.next;
index++;
}
Related
I am new to Java and I am trying to implement the Comparable interface for a linked list. I have a standard linked list.
public class LinkedList<E extends Comparable<E>>{
private static class Node<T> {
private T value;
private Node<T> next;
private Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
private Node<E> head;
private int size=0;
public boolean isEmpty() {
return head == null;
//or
//return size == 0;
}
public void addFirst(E elem) {
if (elem == null) {
throw new NullPointerException();
}
head = new Node<E>(elem, head);
size++;
}
public void addLast(E elem) {
if (elem == null) {
throw new NullPointerException();
}
if (head == null) {
head = new Node<E>(elem, null);
} else {
Node<E> current = head;
while (current.next != null) {
current = current.next;
}
current.next = new Node<E>(elem, null);
}
size++;
}
//adding at a specific index
public void add(E elem, int index) {
if (elem == null) {
throw new NullPointerException();
}
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException(Integer.toString(index));
}
if (index == 0) {
head = new Node<E>(elem, head);
} else {
Node<E> p = head;
for (int i=0; i<(index-1); i++) {
p = p.next;
}
p.next = new Node<E>(elem, p.next);
}
size++;
}
public E removeFirst() {
if (head == null) {
throw new NullPointerException();
}
E saved = head.value;
head = head.next;
size--;
return saved;
}
public E removeLast() {
if (head == null) {
throw new NullPointerException();
}
E saved;
if (head.next == null) {
saved = head.value;
head = null;
} else {
Node<E> p = head;
while (p.next.next != null) {
p = p.next;
}
saved = p.next.value;
p.next = null;
}
size--;
return saved;
}
public int size() {
return size;
}
public String toString() {
String str = "[";
Node<E> p = head;
while (p!=null) {
if (p != head) {
str += ", ";
}
str += p.value;
p = p.next;
}
str += "]";
return str;
}
public int compareTo(Node<E> other){
return Integer.compare(this.value,other.value);
}
}
Currently I am assuming the contents of the list are of type int. When I try to compile, I get the error as
LinkedList.java:144: error: cannot find symbol
return Integer.compare(this.value,other.value);
^
Based on what I can understand, it's because I am trying to compare Objects of type Node and not linkedList, therefore "this" is referring linkedList. I am not sure how I can change my code to be able to compare two nodes. Any help or suggestions is appreciated.
Edit:
Is my general methodology incorrect or just my implementation? Is there another way I should implement compareTo? e.g. Add it as a method in the class node?
value is a field in Node and this in your current compareTo method refers to a the linked list object.
You could make the Node class to implement Comparable as below:
public static class Node<T> implements Comparable<Node<T>> {
// rest of the code
#Override
public int compareTo(Node<T> other) {
// this.value is accessible.
}
}
Now in your LinkedList class write another compareTo method (or any other name as this method is not related to Comparable.compareTo) which would invoke the above.
public int compareTo(Node<E> other) {
return this.head.compareTo(other);
}
NOTE: In your current code, you haven't actually "implemented" the Comparable interface. You have only mentioned that the generic type E is a Comparable type.
You didn't understand this<E extends Comparable<E>>,There are two solutions
1.
public class LinkedList<E extends Comparable<E>>{
//public class LinkedList<E extends Integer>{
private static class Node<T> {
private T value;
private Node<T> next;
private Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
private Node<E> head;
private int size=0;
public int compareTo(Node<E> other){
return this.head.value.compareTo(other.value);
//return Integer.compare(this.head.value, other.value);
}
}
//public class LinkedList<E extends Comparable<E>>{
public class LinkedList<E extends Integer>{
private static class Node<T> {
private T value;
private Node<T> next;
private Node(T value, Node<T> next) {
this.value = value;
this.next = next;
}
}
private Node<E> head;
private int size=0;
public int compareTo(Node<E> other){
//return this.head.value.compareTo(other.value);
return Integer.compare(this.head.value, other.value);
}
}
I am currently trying to understand Singly linked lists.
I don't understand some of the code in the SinglyLinkedList.java class. How can the Node class be called and then assigned like: private Node first;
I would have thought that you would have to do something like this
Node<T> help =new Node<>();
help = first;
If someone could explain, or provide me to a link that would help me, it would be much appreciated.
Thanks!
public class Node<T> {
public T elem;
public Node<T> next;
public Node(T elem) {
this.elem = elem;
next = null;
}
public Node(T elem, Node<T> next) {
this.elem = elem;
this.next = next;
}
#Override
public String toString() {
return "Node{" + "elem=" + elem + '}';
}
}
package list;
/**
*
* #author dcarr
*/
public class SinglyLinkedList<T> implements List<T> {
private Node<T> first;
private Node<T> last;
public SinglyLinkedList() {
first = null;
last = null;
}
#Override
public boolean isEmpty() {
return first == null;
}
#Override
public int size() {
if (isEmpty()){
return 0;
} else {
int size = 1;
Node<T> current = first;
while(current.next != null){
current = current.next;
size++;
}
return size;
}
}
#Override
public T first() {
return first.elem;
}
#Override
public void insert(T elem) {
// if there is nothing in the list
if (isEmpty()){
first = new Node<>(elem);
last = first;
// if the list has elements already
} else {
// the new element will be the next of what was the last element
last.next = new Node<>(elem);
last = last.next;
}
}
#Override
public void remove(T elem) {
if (!isEmpty()){
int index = 0;
Node<T> current = first;
while (current != null && current.elem != elem){
current= current.next;
index++;
}
remove(index);
}
}
#Override
public String toString() {
if (isEmpty()){
return "Empty List";
} else {
String str = first.elem.toString() + " ";
Node<T> current = first;
while(current.next != null){
current = current.next;
str += current.elem.toString() + " ";
}
return str;
}
}
#Override
public void insertAt(int index, T e) {
if (index == 0){
first = new Node<>(e, first);
if (last == null){
last = first;
}
return;
}
Node<T> pred = first;
for (int i = 0; i < index-1; i++) {
pred = pred.next;
}
pred.next = new Node<>(e, pred.next);
System.out.println(pred);
if (pred.next.next == null){
// what does this mean pred.next is?
last = pred.next;
}
}
#Override
public void remove(int index) {
if (index < 0 || index >= size()){
throw new IndexOutOfBoundsException();
} else if (isEmpty()){
return;
}
if (index == 0){
first = first.next;
if (first == null){
last = null;
}
return;
}
Node<T> pred = first;
for (int i = 1; i <= index-1; i++) {
pred = pred.next;
}
// remove pred.next
pred.next = pred.next.next;
if (pred.next == null){
last = pred;
}
}
}
The first field is automatically initialized to null:
private Node<T> first;
I assume there will be some method to add an element at the end like so:
public void add(T element) {
if (first == null) {
first = new Node<T>(element);
last = first;
}
else {
last.next = new Node<>(element);
last = last.next;
}
}
So when you create a new SinglyLinkedList:
SinglyLinkedList<String> sillyList = new SinglyLinkedList<>();
The first and last fields both hold a null reference.
Note that the first method will cause a NullPointerException at this point. A better implementation would be:
#Override
public Optional<T> first() {
if (first != null) {
return Optional.ofNullable(first.elem);
}
else {
return Optional.empty();
}
}
Now if you add an element:
sillyList.add("Adam");
The code executed in the add method is:
first = new Node<>(elem);
last = first;
So first points to a new Node instance with an elem field holding the value "Adam". And last points to that same Node instance.
Some of the methods in this class I would implement differently, for example:
#Override
public void remove(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Index cannot be negative");
}
else if (index == 0 && first != null) {
first = null;
last = null;
}
else {
Node<T> curr = new Node<>("dummy", first);
int c = 0;
while (curr.next != null) {
if (c == index) {
curr.next = curr.next.next;
if (curr.next == null) {
last = curr;
}
return;
}
curr = curr.next;
c++;
}
throw new IndexOutOfBoundsException(String.valueOf(c));
}
Also, some of the methods don't actually exist in the java.util.List interface, like insert, insertAt and first. So these methods must not have the #Override annotation.
I am trying to implement Knuth's Dancing Links algorithm in Java.
According to Knuth, if x is a node, I can totally unlink a node by the following operations in C:
L[R[x]]<-L[x]
R[L[x]]<-R[x]
And revert the unlinking by:
L[R[x]]<-x
R[L[x]]<-x
What am I doing wrongly in my main method?
How do you implement the unlinking and revert in Java?
Here's my main method:
///////////////
DoublyLinkedList newList = new DoublyLinkedList();
for (int i = 0; i < 81; i++) {
HashSet<Integer> set = new HashSet<Integer>();
set.add(i);
newList.addFirst(set);
}
newList.displayList();
// start at 69
newList.getAt(12).displayNode();
//HOW TO IMPLEMENT UNLINK?
//newList.getAt(12).previous() = newList.getAt(12).next().previous().previous();
//newList.getAt(12).next() = newList.getAt(12).previous().next().next();
newList.displayList();
//HOW TO IMPLEMENT REVERT UNLINK?
//newList.getAt(12) = newList.getAt(12).next().previous();
//newList.getAt(12) = newList.getAt(12).previous().next();
System.out.println();
///////////////
Here's the DoublyLinkedList class:
public class DoublyLinkedList<T> {
public Node<T> first = null;
public Node<T> last = null;
static class Node<T> {
private T data;
private Node<T> next;
private Node<T> prev;
public Node(T data) {
this.data = data;
}
public Node<T> get() {
return this;
}
public Node<T> set(Node<T> node) {
return node;
}
public Node<T> next() {
return next;
}
public Node<T> previous() {
return prev;
}
public void displayNode() {
System.out.print(data + " ");
}
#Override
public String toString() {
return data.toString();
}
}
public void addFirst(T data) {
Node<T> newNode = new Node<T>(data);
if (isEmpty()) {
newNode.next = null;
newNode.prev = null;
first = newNode;
last = newNode;
} else {
first.prev = newNode;
newNode.next = first;
newNode.prev = null;
first = newNode;
}
}
public Node<T> getAt(int index) {
Node<T> current = first;
int i = 1;
while (i < index) {
current = current.next;
i++;
}
return current;
}
public boolean isEmpty() {
return (first == null);
}
public void displayList() {
Node<T> current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
System.out.println();
}
public void removeFirst() {
if (!isEmpty()) {
Node<T> temp = first;
if (first.next == null) {
first = null;
last = null;
} else {
first = first.next;
first.prev = null;
}
System.out.println(temp.toString() + " is popped from the list");
}
}
public void removeLast() {
Node<T> temp = last;
if (!isEmpty()) {
if (first.next == null) {
first = null;
last = null;
} else {
last = last.prev;
last.next = null;
}
}
System.out.println(temp.toString() + " is popped from the list");
}
}
I am not familiar with Knuth's Dancing Links algorithm, but found this article which made it quiet clear. In particular I found this very helpful:
Knuth takes advantage of a basic principle of doubly-linked lists.
When removing an object from a list, only two operations are needed:
x.getRight().setLeft( x.getLeft() )
x.getLeft().setRight(> x.getRight() )
However, when putting the object back in the list, all
is needed is to do the reverse of the operation.
x.getRight().setLeft( x )
x.getLeft().setRight( x )
All that is
needed to put the object back is the object itself, because the object
still points to elements within the list. Unless x’s pointers are
changed, this operation is very simple.
To implement it I added setters for linking / unlinking. See comments:
import java.util.HashSet;
public class DoublyLinkedList<T> {
public Node<T> first = null;
public Node<T> last = null;
static class Node<T> {
private T data;
private Node<T> next;
private Node<T> prev;
public Node(T data) {
this.data = data;
}
public Node<T> get() {
return this;
}
public Node<T> set(Node<T> node) {
return node;
}
public Node<T> next() {
return next;
}
//add a setter
public void setNext(Node<T> node) {
next = node;
}
public Node<T> previous() {
return prev;
}
//add a setter
public void setPrevious(Node<T> node) {
prev = node;
}
public void displayNode() {
System.out.print(data + " ");
}
#Override
public String toString() {
return data.toString();
}
}
public void addFirst(T data) {
Node<T> newNode = new Node<T>(data);
if (isEmpty()) {
newNode.next = null;
newNode.prev = null;
first = newNode;
last = newNode;
} else {
first.prev = newNode;
newNode.next = first;
newNode.prev = null;
first = newNode;
}
}
public Node<T> getAt(int index) {
Node<T> current = first;
int i = 1;
while (i < index) {
current = current.next;
i++;
}
return current;
}
public boolean isEmpty() {
return (first == null);
}
public void displayList() {
Node<T> current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
System.out.println();
}
public void removeFirst() {
if (!isEmpty()) {
Node<T> temp = first;
if (first.next == null) {
first = null;
last = null;
} else {
first = first.next;
first.prev = null;
}
System.out.println(temp.toString() + " is popped from the list");
}
}
public void removeLast() {
Node<T> temp = last;
if (!isEmpty()) {
if (first.next == null) {
first = null;
last = null;
} else {
last = last.prev;
last.next = null;
}
}
System.out.println(temp.toString() + " is popped from the list");
}
public static void main(String[] args) {
///////////////
DoublyLinkedList newList = new DoublyLinkedList();
for (int i = 0; i < 81; i++) {
HashSet<Integer> set = new HashSet<Integer>();
set.add(i);
newList.addFirst(set);
}
newList.displayList();
// start at 69
Node node = newList.getAt(12);
node.displayNode(); System.out.println();
//HOW TO IMPLEMENT UNLINK?
node.previous().setNext(node.next);
node.next().setPrevious(node.previous());
//The 2 statements above are equivalent to
//Node p = node.previous();
//Node n = node.next();
//p.setNext(n);
//n.setPrevious(p);
newList.displayList();
//HOW TO IMPLEMENT REVERT UNLINK?
node.previous().setNext(node);
node.next().setPrevious(node);
newList.displayList(); System.out.println();
///////////////
}
}
I have a doubly linked list in my case. And I want to find the max and min element. So I want to use the Collections to find it. Here is my code below for Node first:
public class Node<T> {
Node<T> prev;
Node<T> next;
T data;
public Node(T _data)
{
data = _data;
prev = null;
next = null;
}
public Node(T _data, Node<T> _prev, Node<T> _next)
{
data = _data;
prev = _prev;
next = _next;
}
T getData()
{
return data;
}
public void setNext(Node<T> _next)
{
next = _next;
}
public void setPrev(Node<T> _prev)
{
prev = _prev;
}
public Node<T> getNext()
{
return next;
}
public Node<T> getPrev()
{
return prev;
}
}
And here is my Doubly Linked List class:
public class DoublyLinkedList<T> {
private Node<T> head;
private Node<T> tail;
int listCount = 0;
public void traverseF()
{
Node<T> temp = head;
while(temp != null)
{
System.out.print(temp.getData() + " ");
temp = temp.getNext();
}
}
public void traverseB()
{
Node<T> temp = tail;
while(temp != null)
{
System.out.print(temp.getData() + " ");
temp = temp.getPrev();
}
}
public void insertFirst(T data)
{
Node<T> temp = new Node<T>(data);
if(head == null)
{
head = temp;
tail = temp;
temp.setNext(null);
temp.setPrev(null);
}
else
{
temp.setNext(head);
head.setPrev(temp);
head = temp;
}
}
}
So, my main code is:
import java.util.Collections;
public class glavna {
public static void main(String[] args) {
DoublyLinkedList<Integer> DLL = new DoublyLinkedList<Integer>();
DLL.insertFirst(32);
DLL.insertFirst(22);
DLL.insertFirst(55);
DLL.insertFirst(10);
DLL.traverseF();
Integer max = Collections.max(DLL);
}
}
How exactly do I call the Collections.max or Collections.min method? Isn't the list only necessary to find the max/min elements?
public T getMin()
{
Node<T> temp = head;
T min = head.getData();
while(temp.getNext() != null)
{
if(temp.getData() < min) // error
{
//min = temp.getData();
}
}
}
To implement getMin with generics you need to be able to compare them. You can, for instance, provide a custom Comparator to your method:
public T getMin(Comparator<? super T> comparator) {
Node<T> temp = head.getNext();
T min = head.getData();
while(temp != null) {
T candidateValue = temp.getData();
if (comparator.compare(candidateValue, min) < 0) { // equivalent to candidate < min
min = candidateValue;
}
temp = temp.getNext();
}
return min;
}
Then, calling your method for Integer :
getMin(new Comparator<Integer>() {
#Override
public int compare(Integer arg0, Integer arg1) {
return arg0.compareTo(arg1);
}
});
Another approach is to make your list only keep Comparable items :
public class DoublyLinkedList<T extends Comparable<? super T>> {
and then have your getMin() method use compareTo method :
public T getMin() {
Node<T> temp = head.getNext();
T min = head.getData();
while(temp != null) {
T candidateValue = temp.getData();
if (candidateValue.compareTo(min) < 0) { // equivalent to candidate < min
min = candidateValue;
}
temp = temp.getNext();
}
return min;
}
Second approach is less verbose, as Integer is Comparable (i.e. implements Comparable for you already), so you won't need to change any other code.
You list is not a Collection, so you cannot use Collections with it.
The Collections.max method expects an argument which implements Collection. The easiest way would probably be to extend AbstractCollection and add these methods:
#Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private Node<T> node = head;
#Override
public boolean hasNext() {
return node != null;
}
#Override
public T next() {
T next = node.data;
node = node.getNext();
return next;
}
};
}
#Override
public int size() {
int size = 0;
Node<T> node = head;
while (node != null) {
size++;
node = node.getNext();
}
return size;
}
I'm wondering if this has something to do with how I specified my Singly Linked List class, but the problem is eluding me.
Here is the Singly Linked List class:
class SLList {
private static Node head;
private static long size;
public SLList() {
head = new Node(null, null);
setSize(0);
}
static class Node {
private Object data;
private Node next;
public Node(Object newData, Node n) {
data = newData;
next = n;
}
public Node getNext() {
return next;
}
public void setElement(Object element) {
data = element;
}
public void setNext(Node newNext) {
next = newNext;
}
public String toString() {
String result = data + " ";
return result;
}
public Object getObject() {
return data;
}
}
public Node getHead() {
return head;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public void addLast(Object object) {
Node temp = head;
while(temp.next != null) {
temp = temp.next;
}
temp.next = new Node(object, null);
size++;
}
public void remove(Object object) {
Node pre = head;
Node temp = head.next;
while(temp.next != null) {
pre = temp;
temp = temp.next;
if(temp.data.equals(object)) {
pre = temp.next;
temp = temp.next.next;
size--;
}
}
}
public void printElements() {
Node temp = head;
if(temp.next == null) {
System.out.println("List is empty.");
}
else {
while(temp.next != null) {
temp = temp.next;
System.out.println(temp.data);
}
}
}
}
This is the Set class with a method to add new values to the lists, barring duplicates already in the list:
public class Set {
SLinkedList aList;
SLinkedList bList;
SLinkedList cList;
SLinkedList dList;
public Set() {
aList = new SLinkedList();
bList = new SLinkedList();
cList = new SLinkedList();
dList = new SLinkedList();
}
public SLinkedList getList(char x) {
if(x == 'a') {
return aList;
}
else if(x == 'b') {
return bList;
}
else if(x == 'c') {
return cList;
}
else {
return dList;
}
}
public boolean addElement(SLinkedList list, Object newData) {
SLinkedList.Node newNode = new SLinkedList.Node(newData, null);
SLinkedList.Node traverseNode = list.getHead();
while(traverseNode.getNext() != null) {
traverseNode = traverseNode.getNext();
if(traverseNode.getObject().equals(newNode.getObject())) {
System.out.println("This data is already in the list.");
return false;
}
}
list.addLast(newData);
System.out.println("Node added!");
return true;
}
public void fillList() {
aList.addLast("dog");
aList.addLast(4);
bList.addLast("test");
System.out.println("aList: ");
aList.printElements();
System.out.println("bList: ");
bList.printElements();
}
}
This is the output when I try to use fillList() to add values to the first Singly Linked List, aList
aList:
dog 4 test
bList:
dog 4 test
As you can see, adding values to aList adds the same values to bList. Any help would be greatly appreciated!
This:
private static Node head;
means you have one head for all your instances of SLLIst. So all SLList instance share the same head.
This should be a member of your class, and as such you'll have an instance of head per instance of SLLIst.
e.g.
private Node head;
The same applies to your size field. I don't think you'll need any static members.