I'm trying to implement an insertAfterNth method that inserts an element after the nth(starting from 1, not 0) element on a doubly linked list. And, I'm stuck in setting the previous node to the node that I'm trying to insert. I need some help on figuring out the problem. Thanks.
public class DListNode {
public DListNode next;
public DListNode prev;
public int item;
...
}
public void insertAfterNth(int n, int item) {
if (n > length() || n < 1) {
System.out.println("error: out of bounds");
return;
}
else if (n == length()) {
insertEnd(item);
}
DListNode walker = head;
int i = 1;
while (i != n) {
i++;
walker = walker.next;
}
DListNode node = new DListNode(item);
node.next = walker.next;
walker.next.prev = node; /* not sure if this line of code is right, regardless this method is giving me errors(I'm most certain that this line is causing the problem)*/
walker.next = node;
node.prev = walker;
size++;
}
try using
(walker.next).prev
I might be wrong.
The code is mostly correct. You must add a method for inserting at the start of the list, but from your description/method name, it seems that you insert after a node so there may be no point in adding insertion at the start. You must check for the case when the head node is null. Another sugestion is to return a boolean value if the operation was successful. Another good return can be the newly inserted node or null if the operation failed. You may also throw an exception if you don't wish to return a value.
public class DoubleLinkedList {
private DListNode head;
private DListNode tail;
private int size;
private class DListNode {
private DListNode next;
private DListNode prev;
private int item;
private DListNode(final int item) {
this.item = item;
}
}
public void insertAfterNth(final int n, final int item) {
if (size == 0) {
System.out.println("error: list is empty");
} else if ((n > size) || (n < 1)) {
System.out.println("error: out of bounds");
return;
} else if (n == size) {
insertEnd(item);
}
DListNode walker = head;
int i = 1;
while (i < n) {
i++;
walker = walker.next;
}
DListNode node = new DListNode(item);
node.next = walker.next;
walker.next.prev = node;
walker.next = node;
node.prev = walker;
size++;
}
private void insertEnd(int item) {
size++;
final DListNode newItem = new DListNode(item);
if (head == null) {
head = newItem;
tail = newItem;
} else {
tail.next = newItem;
newItem.prev = tail;
tail = newItem;
}
}
public void add(final int item) {
insertEnd(item);
}
//the rest of operations you wish to implement
}
Related
I have just seen this wonderful code from this question "Generic Linked List in java" here on Stackoverflow. I was wandering on how do you implement a method remove (to remove a single node from the linkedlist), size (to get the size of list) and get (to get the a node). Could someone please show me how to do it?
public class LinkedList<E> {
private Node head = null;
private class Node {
E value;
Node next;
// Node constructor links the node as a new head
Node(E value) {
this.value = value;
this.next = head;//Getting error here
head = this;//Getting error here
}
}
public void add(E e) {
new Node(e);
}
public void dump() {
for (Node n = head; n != null; n = n.next)
System.out.print(n.value + " ");
}
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("world");
list.add("Hello");
list.dump();
}
}
Your implementation of LinkedList for operation remove(), size() and contains()
looks like this:
static class LinkedList<Value extends Comparable> {
private Node head = null;
private int size;
private class Node {
Value val;
Node next;
Node(Value val) {
this.val = val;
}
}
public void add(Value val) {
Node oldHead = head;
head = new Node(val);
head.next = oldHead;
size++;
}
public void dump() {
for (Node n = head; n != null; n = n.next)
System.out.print(n.val + " ");
System.out.println();
}
public int size() {
return size;
}
public boolean contains(Value val) {
for (Node n = head; n != null; n = n.next)
if (n.val.compareTo(val) == 0)
return true;
return false;
}
public void remove(Value val) {
if (head == null) return;
if (head.val.compareTo(val) == 0) {
head = head.next;
size--;
return;
}
Node current = head;
Node prev = head;
while (current != null) {
if (current.val.compareTo(val) == 0) {
prev.next = current.next;
size--;
break;
}
prev = current;
current = current.next;
}
}
}
here is my code
public class LinkedListDeque<T> implements Deque {
private Node sentinel;
private int size;
private static class Node<T> {
private T item;
private Node pre;
private Node next;
public Node(T i, Node p, Node n) {
item = i;
pre = p;
next = n;
}
public LinkedListDeque() {
size = 0;
sentinel = new Node(null, null, null);
sentinel.next = sentinel;
sentinel.pre = sentinel;
}
public LinkedListDeque(T item) {
size = 1;
Node first = new Node(item, sentinel, sentinel);
sentinel = new Node(null, first, first);
}
public Object getRecursive(int index) {}
}
I just can't figure out how to do it. I can do it in a interation way. I don't know where to start to build a recursion methods.
public Node getNode(Node n, int index, int pos) {
if (index == pos) {
return n;
}
if (index > pos || n == null) {
return null;
}
return getNode(n.next, index, pos++);
}
I believe this is what you want, and the initial call is with pos=0 and the head of the LinkedList.
I think you need to look up how recursion works though, because you failed to even attempt the problem.
I have to sort through a LinkedList, but i can't figure out why it only sorts it once and then stops. I am having a hard time understanding generic types and how to use them. Most of the examples i found were about sorting integer arrays, but i still couldn't translate those examples into my sort method. Anything that could help me understand how to sort this would be greatly appreciated.
public void sort() {
Node<T> current = head;
while(current != null){
if(current.getNext()!=null && current.getItem().compareTo(current.getNext().getItem()) < 0){
T temp = current.getItem();
current.setItem(current.getNext().getItem());
current.getNext().setItem(temp);
}
current = current.getNext();
}
current = head;
}
Here is my LinkedList class
public class LinkedList<T extends Comparable<T>> implements LinkedList161<T> {
protected Node<T> head;
protected int size;
public LinkedList() {
head = null;
size = 0;
}
public void add(T item, int index) {
if(index < 0 || index > size){
throw new IndexOutOfBoundsException("out of bounds");
}
if(index == 0){
head = new Node<T>(item, head);
}
else{
Node<T> current = head;
for(int i = 0; i < index -1; i ++){
current = current.getNext();
}
current.setNext(new Node<T>(item, current.getNext()));
}
size++;
}
public void addFirst(T item) {
head = new Node<T>(item, head);
size++;
}
public void addToFront(T item) {
head = new Node<T>(item, head);
size++;
}
public void addToBack(T item) {
if(head == null){
head = new Node<T>(item);
size++;
}
else{
Node<T> temp = head;
while(temp.getNext() != null){
temp = temp.getNext();
}
temp.setNext(new Node<T>(item));
size++;
}
}
public void remove(int index) {
if(index < 0 || index > size){
System.out.println("Index out of bounds");
}
if(index == 0){
head = head.getNext();
}else{
Node<T> current = head;
for(int i = 0; i < index;i++){
current = current.getNext();
}
current.setNext(current.getNext().getNext());
}
size--;
}
public T get(int index){
Node<T> p = head;
for(int i = 0; i < index;i++){
p = p.getNext();
}
return p.getItem();
}
public void clear() {
head = null;
size = 0;
}
public int size() {
return size;
}
#Override
public String toString() {
String result = "";
if (head == null)
return result;
for (Node<T> p = head; p != null; p = p.getNext()) {
result += p.getItem() + "\n";
}
return result.substring(0,result.length()-1); // remove last \n
}
#Override
public void sort() {
Node<T> current = head;
for(int i = 0; i < size;i++){
if(current.getNext()!=null && current.getItem().compareTo(current.getNext().getItem()) < 0){
T temp = current.getItem();
current.setItem(current.getNext().getItem());
current.getNext().setItem(temp);
}
current = current.getNext();
}
current = head;
}
}
Here is my Node class
public class Node<T> implements Node161<T>{
protected T item;
protected Node<T> next;
public Node(T item, Node<T> next) {
setItem(item);
setNext(next);
}
public Node(T item) {
setItem(item);
}
public T getItem() {
return item;
}
public void setItem(T i) {
item = i;
}
public void setNext(Node<T> n) {
next = n;
}
public Node<T> getNext() {
return next;
}
#Override
public String toString() {
return item.toString();
}
}
Your implementation of sort does just one step of sorting: it orders adjacent items and after this step things get better but the whole collection will not be sorted. You should repeat this step until your collection gets sorted.
Note that this algorithm is not efficient. You should look at some more sophisticated approach like merge sort
Wiki merge sort article now includes a simple but fast bottom up merge sort for linked lists that uses a small array (usually 26 to 32) of pointers to the first nodes of a list, where array[i] is either null or points to a list of size 2 to the power i. Unlike some other approaches, there's no scanning of lists, instead, the array is used along with a common merge function that merges two already sorted lists. Link to article:
http://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists
The problem I am facing is figuring out how to write a method
public SingleLinkedList copy(Node <E> node) {
}
To return a copy of the list. I have tried:
public SingleLinkedList copy(Node <E> node) {
SingleLinkedList<E> temp = new SingleLinkedList<E>();
Node<E> ref = head;
for(Node<E> n = ref ;ref!= null; n = n.next){
temp.add(n, ref.data);
ref = ref.next;
}
return temp;
}
I created a new list called temp, changed head to ref, iterate through the list and add it to the new list and return the new list, but there's an error with temp.add(n, ref.data).
What am I possibly doing wrong?
class SingleLinkedList<E> {
private static class Node<E> {
private E data;//removed final * private final E data
private Node<E> next;
private Node(E item) {
data = item;
}
}
private Node<E> head;
private int size;
/* Insert item at index, returns true if add is successful. */
public boolean add(int index, E item) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("" + index);
}
if (index == 0) { // adding to the front
Node<E> t = head;
head = new Node<>(item);
head.next = t;
} else { // adding anywhere other than front
Node<E> left = getNode(index - 1);
Node<E> node = new Node(item);
Node<E> right = left.next;
left.next = node;
node.next = right;
}
size++;
return true;
}
/* Add item at end of list, returns true if successful. */
public boolean add(E item) {
return add(size, item);
}
/* Return item at index */
public E get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("" + index);
}
return getNode(index).data;
}
/* Return the number of items */
public int size() {
return size;
}
/* Returns a string representation of the list */
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ ");
for (Node<E> n = head; n != null; n = n.next) {
sb.append(n.data);
sb.append(" ");
}
sb.append("]");
return sb.toString();
}
/* Return the node at location index */
private Node<E> getNode(int index) {
Node<E> n = head;
for (int i = 0; i < index; i++)
n = n.next;
return n;
}
The problem is you need to pass the position as an int. I also removed the Node n because you do not need it anyways.
I think this should work.
public SingleLinkedList copy() {
SingleLinkedList<E> temp = new SingleLinkedList<E>();
int i = 0;
for(Node<E> ref = head ;ref!= null; ref = ref.next){
temp.add(i++, ref.data);
}
return temp;
}
EDIT: I forgot to drop the parameter you do not need it at all.
I am trying to learn data structure, but I ran into the dreaded NullPointerException and I am not sure how to fix it.
My SinglyLinkedList<E> class implements an interface, LinkedList, where I redefined some methods like, add(), get(), contains(), and more.
The NullPointerException happens when I use the clear() method. It points at the method removeLast() under nodeBefore.setNext(null). It also points to the clear() method under remove(head.getElement()).
Also, if there is anything I can improve upon in my code please let me know.
public class SinglyLinkedList<E> implements LinkedList<E> {
private class Node<E> {
public Node<E> next;
public E element;
public Node(E element) {
this.element = element;
}
public Node (E element, Node<E> next) {
this.element = element;
this.next = next;
}
public E getElement() {
return element;
}
public Node<E> getNext() {
return next;
}
public void setElement(E element) {
this.element = element;
}
public void setNext(Node<E> next) {
this.next = next;
}
public String toString() {
return ("[" + element + "] ");
}
}
public Node<E> head;
public Node<E> tail;
public int total;
public SinglyLinkedList() {
this.head = null;
this.tail = null;
this.total = 0;
}
public E get(int index) {
if (index < 0 || index > size()) {
return null;
}
if (index == 0) {
return head.getElement();
}
Node<E> singly = head.getNext();
for (int i = 1; i < index; i ++) {
if (singly.getNext() == null) {
return null;
}
singly = singly.getNext();
}
System.out.println("\n" + singly.getElement());
return singly.getElement();
}
public void add(E element) {
Node<E> singlyAdd = new Node<E>(element);
if (tail == null) {
head = singlyAdd;
tail = singlyAdd;
} else {
tail.setNext(singlyAdd);
tail = singlyAdd;
}
total++;
}
public void display() {
if (head == null) {
System.out.println("empty list");
} else {
Node<E> current = head;
while (current != null) {
System.out.print(current.toString());
current = current.getNext();
}
}
}
public boolean contains(E data) {
if (head == null) {
return false;
}
if (head.getElement() == data) {
System.out.println(head);
return true;
}
while (head.getNext() != null) {
head = head.getNext();
if (head.getElement() == data) {
System.out.println(head);
return true;
}
}
return false;
}
private Node<E> removeFirst() {
if (head == null) {
System.out.println("We cant delete an empty list");
}
Node<E> singly = head;
head = head.getNext();
singly.setNext(null);
total--;
return singly;
}
private Node<E> removeLast() {
Node<E> nodeBefore;
Node<E> nodeToRemove;
if (size() == 0) {
System.out.println("Empty list");
}
nodeBefore = head;
for (int i = 0; i < size() - 2; i++) {
nodeBefore = nodeBefore.getNext();
}
nodeToRemove = tail;
nodeBefore.setNext(null);
tail = nodeBefore;
total--;
return nodeToRemove;
}
public E remove(int index) {
E hold = get(index);
if (index < 0 || index >= size()) {
return null;
} else if (index == 0) {
removeFirst();
return hold;
} else {
Node<E> current = head;
for (int i = 1; i < index; i++) {
current = current.getNext();
}
current.setNext(current.getNext().getNext());
total--;
return hold;
}
}
public int size() {
return getTotal();
}
public boolean remove(E data) {
Node<E> nodeBefore, currentNode;
if (size() == 0) {
System.out.println("Empty list");
}
currentNode = head;
if (currentNode.getElement() == data) {
removeFirst();
}
currentNode = tail;
if (currentNode.getElement() == data) {
removeLast();
}
if (size() - 2 > 0) {
nodeBefore = head;
currentNode = head.getNext();
for (int i = 0; i < size() - 2; i++) {
if (currentNode.getElement() == data) {
nodeBefore.setNext(currentNode.getNext());
total--;
break;
}
nodeBefore = currentNode;
currentNode = currentNode.getNext();
}
}
return true;
}
public void clear() {
while (head.getNext() != null) {
remove(head.getElement());
}
remove(head.getElement());
}
private int getTotal() {
return total;
}
}
For your clear method, I don't see that you do any per element cleanup, and the return type is void, so all you want is an empty list. The easiest way is to simply clear everything, like in the constructor:
public void clear() {
this.head = null;
this.tail = null;
this.total = 0;
}
Another comment:
in contains, you do
while (head.getNext() != null) {
head = head.getNext();
if (head.getElement() == data) {
System.out.println(head);
return true;
}
}
which may have two problems (where the first applies to the entire class),
you compare with == data which compares references, where you probably want to compare values with .equals(data)
Edit: I.e. n.getElement().equals(data) instead of n.getElement() == data.
(Or, if n and data may be null, something like (data != null ? data.equals(n.getElement()) : data == n.getElement())
you use the attribute head as the scan variable which modifies the state of the list. Do you really want that?
The problem arises when you delete the last element within clear: remove(head.getElement());. For some reason, you first remove the head and then the tail. But when calling removeLast, you use the head (which is already null). Within removeLast this is the line, which causes the NullPointerException: nodeBefore.setNext(null);.
My advice would be to write the clear() method as #bali182 has suggested:
public void clear() {
this.head = null;
this.tail = head;
this.total = 0;
}
One advice: if you are writing methods to search or delete entries, you should never use == when dealing with objects (or even better: don't use == at all when dealing with objects). You may want to read this thread.
From within clear method, you are calling remove(head.getElement()); meaning you are trying to call LinkedList's remove method. And since you are overriding each functionality and so is add, you don't maintain internal state of LinkedList and hence you get exception. Code in remove is:
public boolean remove(Object o) {
if (o==null) {
for (Entry<E> e = header.next; e != header; e = e.next) {
if (e.element==null) {
So here since you are not using functionality of LinkedList, header would be null and doing header.next would return NullPointerException.