Double Linked List - linked-list

//I have a single linked list that looks like this
node head = new Node ();
head.info = 3;
head.next = new Node ();
head.next.info = 6 ();
head.next.next = new Node ();
head.next.next.info = 9;
head.next.next.next = null;
//How would I write a double linked list?
class Double Node
{
info;
doubleNode prev;
doubleNode next;
}

Here is the part for creating a double linked list and adding nodes to it.
You can update it by adding remove and insert functions as you want.
class Node{
Node prev;
Node next;
int value;
public Node(int value) {
this.value = value;
}
}
class DoubleLinkedList{
Node head;
Node tail;
public DoubleLinkedList(Node head) {
this.head = head;
this.tail = head;
head.next = null;
head.prev = null;
}
public void addNode(Node node){
tail.next = node;
node.prev = tail;
tail = node;
}
}
public class Main {
public static void main(String args[]){
Node head= new Node(3);
DoubleLinkedList list = new DoubleLinkedList(head);
list.addNode(new Node(5));
list.addNode(new Node(6));
list.addNode(new Node(7));
list.addNode(new Node(8));
}
}

This would be the idea:
node head = new Node();
head.info = 3;
node prev, actual, next;
prev = head;
actual.prev = prev;
actual.info = 6;
actual = actual.next = new Node();
actual.prev = prev;
actual = actual.next = new Node();
actual.info = 9;
...
Assuming that you will have the behavior in your example, you can automate it with a function, in c# would be something like:
function GetDoubleLinkedList(Node head, int from, int end, int jumps)
{
head.info = from;
node prev = head, actual, next;
for(var i = from+jumps; i <= end; i+=jumps)
{
actual.prev = prev;
actual.info = i;
actual = actual.next = new Node();
}
actual.info = end;
return head;
}
//...
//then you can do
node head = new Node();
head = GetDoubleLinkedList(head, 3, 9, 3);
//...

Double linked list are like single linked list with the exception that they have two pointer in the declaration of structure
a previous pointer and a next pointer
For sample implementation see this link

Here is an implementation of a DoubleLinkedList in Java (along with some examples that might help you understand how it's working):
public class Node {
public int value;
public Node prev;
public Node next;
public Node(int value) {
this.value = value;
this.prev = null;
}
public Node(int value, Node prev) {
this.value = value;
this.prev = prev;
}
public Node add(int value) {
if(this.next == null) {
this.next = new Node(value, this);
} else {
this.next.add(value);
}
return this;
}
public Node last() {
if(this.next == null) {
return this;
} else {
return this.next.last();
}
}
public String toString() {
String out = value+" ";
if(this.next != null) {
out += this.next.toString();
}
return out;
}
public static void main(String...arg) {
Node list = (new Node(3)).add(6).add(5).add(9);
System.out.println(list.toString());
//Output:3 6 5 9
System.out.println(list.last().toString());
//Output:9
System.out.println(list.last().prev.prev.toString());
//Output:6 5 9
}
}

You can use following DoubleLinkedList class.
public class DoubleLinkedList<T>
{
Node<T> start;
Node<T> end;
public void AddFirst(T dataToAdd)
{
Node<T> tmp = new Node<T>(dataToAdd);
if (start == null)
{
start = tmp;
end = start;
return;
}
start.previous = tmp;
tmp.next = start;
start = tmp;
if (start.next == null)
{
end = start;
}
}
public void AddLast(T dataToAdd)
{
if (start == null)
{
AddFirst(dataToAdd);
return;
}
Node<T> tmp = new Node<T>(dataToAdd);
end.next = tmp;
tmp.previous = end;
end = tmp;
}
public T RemoveFirst()
{
if (start == null) return default(T);
T saveVal = start.data;
start = start.next;
start.previous = null;
if (start == null) end = null;
return saveVal;
}
public T RemoveLast()
{
if (start == null) return default(T);
T saveVal = end.data;
end = end.previous;
end.next = null;
if (start == null) end = null;
return saveVal;
}
public void PrintAll()
{
Node<T> tmp = start;
while (tmp != null)
{
Console.WriteLine(tmp.data.ToString());
tmp = tmp.next;
}
}
}
And Use the following Node class
class Node<T>
{
public T data;
public Node<T> next;
public Node<T> previous;
public Node(T newData)
{
data = newData;
next = null;
previous = null;
}
}

Related

Java - Writing method for public int indexOf(T element) in a double linked list

Below I have the int indexOf(T element) method for a double linked list. I need help with the code to make sure it functions properly. The method should return the first occurence of the element in the list or -1 if element is not in the list. Below is the node class it uses. The IUDoubleLinkedList.java class implements IndexedUnsortedList.java which is where the indexOf method comes from. I tried using my indexOf method from my single linked list class but it's not the same so I hope to understand why it would be different and what code is used that is different between the the single and double linked list.
public class IUDoubleLinkedList<T> implements IndexedUnsortedList<T> {
private Node<T> head, tail;
private int size;
private int modCount;
public IUDoubleLinkedList() {
head = tail = null;
size = 0;
modCount = 0;
This is the indexOf(T element) method
#Override
public int indexOf(T element) {
// TODO Auto-generated method stub
return 0;
}
Below is the Node.java class it uses
public class Node<T> {
private Node<T> nextNode;
private T element;
private Node<T> prevNode;
/**
* Creates an empty node.
*/
public Node() {
nextNode = null;
element = null;
}
/**
* Creates a node storing the specified element.
*
* #param elem
* the element to be stored within the new node
*/
public Node(T element) {
nextNode = null;
this.element = element;
setPrevNode(null);
}
/**
* Returns the node that follows this one.
*
* #return the node that follows the current one
*/
public Node<T> getNextNode() {
return nextNode;
}
/**
* Sets the node that follows this one.
*
* #param node
* the node to be set to follow the current one
*/
public void setNextNode(Node<T> nextNode) {
this.nextNode = nextNode;
}
/**
* Returns the element stored in this node.
*
* #return the element stored in this node
*/
public T getElement() {
return element;
}
/**
* Sets the element stored in this node.
*
* #param elem
* the element to be stored in this node
*/
public void setElement(T element) {
this.element = element;
}
#Override
public String toString() {
return "Element: " + element.toString() + " Has next: " + (nextNode != null);
}
public Node<T> getPrevNode() {
return prevNode;
}
public void setPrevNode(Node<T> prevNode) {
this.prevNode = prevNode;
}
}
Check the following code, hope I helped you!
Insert item at head as well as tail end
public void insertItem(T elem) {
/* if head and tail both are null*/
if(head == null || tail == null) {
head = new Node<T>(elem);
tail = new Node<T>(elem);
}else {
Node<T> tempItem = new Node<T>();
tempItem.setElement(elem);
/* insert at head end /*
tempItem.setNextNode(head);
head.setPrevNode(tempItem);
head = tempItem;
Node<T> tempItem1 = new Node<T>();
tempItem1.setElement(elem);
/* append at tail end */
tail.setNextNode(tempItem1);
tempItem1.setPrevNode(tail);
tail = tempItem1;
}
size += 1;
}
Print item from head end
public void printItemsFromHead() {
while(head != null) {
System.out.print(head.getElement()+" --> ");
head = head.getNextNode();
}
}
Print item from tail end
public void printItemsFromTail() {
Node<T> temp = null;
while(tail != null) {
temp = tail;
System.out.print(tail.getElement()+" --> ");
tail = tail.getPrevNode();
}
/*System.out.println();
while(temp != null) {
System.out.print(temp.getElement()+" --> ");
temp = temp.getNextNode();
}*/
}
Implemention of indexOf function
#Override
public int indexOf(T element) {
int result = -1;
int headIndex = 0;
int tailIndex = size;
while(head != null && tail != null) {
if(head.getElement().equals(element)) {
result = headIndex;
break;
}
/*
if(tail.getElement().equals(element)) {
result = tailIndex;
break;
} */
head = head.getNextNode();
tail = tail.getPrevNode();
headIndex += 1;
tailIndex -= 1;
}
return result;
}
Driver class
public class Driver {
#SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void main(String[] args) {
UDoubleLinkedList uDoubleLinkedList = new UDoubleLinkedList();
uDoubleLinkedList.insertItem(1);
uDoubleLinkedList.insertItem(2);
uDoubleLinkedList.insertItem(3);
uDoubleLinkedList.insertItem(4);
uDoubleLinkedList.insertItem(5);
System.out.println(uDoubleLinkedList.indexOf(1));
}
}

Android MediatorLiveData to combine multiple LiveData results into single LiveData object (In Java)

I am using 2 LiveDatas from separate tables into the repository of my application. I add the two LiveDatas as sources to the CustomMediatorLiveData class which extends MediatorLiveData.
In the onChanged callback of addSource method for each LiveData, I send the values of both the LiveDatas into a method that combines both and returns a single LiveData which is set as the value for the CustomMediatorLiveData object. I am creating an object of this CustomMediatorLiveData in my Repository and passing the two LiveDatas as parameters for the constructor.
This runs and doesn't give any error but it is messing up the data within the LiveData itself.
example: If the date was originally 15th August 2020 then it can be something like 14th August 0001.
CustomMediatorLiveData:
public class CustomMediatorLiveData extends MediatorLiveData<List<Object>> {
private List<Note> notes = Collections.emptyList();
private List<RecurringTask> recurringTasks = Collections.emptyList();
public CustomMediatorLiveData(LiveData<List<Note>> liveNotes, LiveData<List<RecurringTask>> liveRecurringTasks) {
addSource(liveNotes, notes1 -> {
if (notes1 != null) {
this.notes = notes1;
}
setValue(combineData(notes,recurringTasks));
});
addSource(liveRecurringTasks, recurringTasks1 -> {
if (recurringTasks1 != null) {
this.recurringTasks = recurringTasks1;
}
setValue(combineData(notes,recurringTasks));
});
}
// This method adds the 2 lists into one and sorts them based on dates and priority.
private List<Object> combineData(List<Note> notes, List<RecurringTask> recurringTasks) {
List<Object> combinedList = new ArrayList<>();
if (notes != null && !notes.isEmpty())
combinedList.addAll(notes);
if(recurringTasks!=null && !recurringTasks.isEmpty())
combinedList.addAll(recurringTasks);
Collections.sort(combinedList, new Comparator<Object>() {
#Override
public int compare(Object o1, Object o2) {
Date d1, d2;
Note n1 = null, n2 = null;
RecurringTask r1 = null, r2 = null;
if (o1 instanceof Note && o2 instanceof Note) {
int hmm = Boolean.compare(((Note) o2).isPriority(), ((Note) o1).isPriority());
if (hmm != 0)
return hmm;
}
if (o1 instanceof Note) {
d1 = ((Note) o1).getEnd_date();
n1 = ((Note) o1);
} else {
d1 = ((RecurringTask) o1).getEnd_date();
r1 = ((RecurringTask) o1);
}
if (o2 instanceof Note) {
d2 = ((Note) o2).getEnd_date();
n2 = ((Note) o2);
} else {
d2 = ((RecurringTask) o2).getEnd_date();
r2 = ((RecurringTask) o2);
}
if (n1 != null) {
if (r2 != null) {
if (n1.isPriority()) {
return -1;
}
}
}
if (n2 != null) {
if (r1 != null) {
if (n2.isPriority()) {
return 1;
}
}
}
long l1 = d1.getTime() - d2.getTime();
if (l1 > 0) {
return 1;
} else if (l1 < 0) {
return -1;
} else {
return 0;
}
}
});
return combinedList;
}
}
Note Repository class:
public class NoteRepository {
private String DB_NAME = "db_task";
Context context;
private RecurringDao recurringDao;
private LiveData<List<RecurringTask>> upcomingRecurringTasks;
private LiveData<List<Note>> upcomingTasks;
private CustomMediatorLiveData customMediatorLiveData;
private NoteDatabase noteDatabase;
public NoteRepository(Context context) {
noteDatabase = NoteDatabase.getInstance(context);
recurringDao = noteDatabase.recurringDao();
upcomingRecurringTasks = recurringDao.getUpcomingRecurringTask();
upcomingTasks = noteDatabase.daoAccess().fetchUpcomingTasks();
this.context = context;
customMediatorLiveData = new CustomMediatorLiveData(upcomingTasks, upcomingRecurringTasks);
}
public LiveData<List<Object>> getCustomMediatorLiveData() {
return customMediatorLiveData;
}
public LiveData<List<RecurringTask>> getUpcomingRecurringTasks() {
return upcomingRecurringTasks;
}
public LiveData<List<Note>> fetchUpcomingTasks() {
return NoteDatabase.getInstance(context).daoAccess().fetchUpcomingTasks();
}
}
I have tried using the MediatorLiveData object and add the two LiveData sources to it in the repository itself and the same issue persists.
What is the correct way to implement this? How to combine 2 LiveDatas into a single LiveData that can be observed.

I have no idea why i have error Exception in thread "main" java.lang.NullPointerException

I tried to use reverseBystack, reverseBylink and remove.. but I don't know why when i use these functions, it has error like this.
Exception in thread "main" java.lang.NullPointerException
at LinkedQueue$Node.access$200(LinkedQueue.java:44)
at LinkedQueue.reverseBylink(LinkedQueue.java:185)
at LinkedQueue.main(LinkedQueue.java:238)
void reverseByStack() - This method reverses the order of the items in the linked list (first
becomes last and last becomes first) using a stack data strucenter code hereture`
• void reverseByLinks() - This method also reverses the order of the items in the linked list.
It should not create a new list or use a stack. It should only reverse the order of the nodes by
modifying the next values for each node in the list.
• int remove(Item item) - This method scans the queue for occurrences of item and removes
them from the queue. It returns the number of items deleted from the queue.
these are what i want to make.
enter code here public class LinkedQueue<Item> implements Iterable<Item> {
private int N; // number of elements on queue
private Node first; // beginning of queue
private Node last; // end of queue
// helper linked list class
private class Node {
private Item item;
private Node next;
}
public LinkedQueue() {
first = null;
last = null;
N = 0;
assert check();
}
public boolean isEmpty() {
return first == null;
}
public int size() {
return N;
}
public Item peek() {
if (isEmpty()) throw new NoSuchElementException("Queue
underflow");
return first.item;
}
public void enqueue(Item item) {
Node oldlast = last;
last = new Node();
last.item = item;
last.next = null;
if (isEmpty()) first = last;
else oldlast.next = last;
N++;
assert check();
}
public Item dequeue() {
if (isEmpty()) throw new NoSuchElementException("Queue
underflow");
Item item = first.item;
first = first.next;
N--;
if (isEmpty()) last = null; // to avoid loitering
assert check();
return item;
}
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
private boolean check() {
if (N == 0) {
if (first != null) return false;
if (last != null) return false;
}
else if (N == 1) {
if (first == null || last == null) return false;
if (first != last) return false;
if (first.next != null) return false;
}
else {
if (first == last) return false;
if (first.next == null) return false;
if (last.next != null) return false;
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N) return false;
// check internal consistency of instance variable last
Node lastNode = first;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
if (last != lastNode) return false;
}
return true;
}
void reverseBystack(){
Stack<Item> s = new Stack<>();
Item item;
while (s.isEmpty() != true){
item = dequeue();
s.push(item);
}
while(s.isEmpty() != true){
item = s.pop();
enqueue(item);
}
}
void reverseBylink() {
Node prev = null;
Node current = this.first;
Node next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
prev.next = current.next;
}
int remove(Item item){
Node cur = first;
Node prev = last;
while(cur != null) {
if(cur.item.equals(item))
System.out.println(cur.item);
}
cur = cur.next;
prev = cur.next;
return 0;
}
public Iterator<Item> iterator() {
return new ListIterator();
}
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() { return current != null;
}
public void remove() { throw new
UnsupportedOperationException(); }
public Item next() {
if (!hasNext()) throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
/**
* Unit tests the <tt>LinkedQueue</tt> data type.
*/
public static void main(String[] args) {
LinkedQueue<String> q = new LinkedQueue<String>();
while (!StdIn.isEmpty()) {
String item = StdIn.readString();
if (!item.equals("-")) q.reverseBylink();
else if (!q.isEmpty()) StdOut.print(q.dequeue() + " ");
}
StdOut.println("(" + q.size() + " left on queue)");
}
}

Implementing stacks, ques using linked lists. Difference between "=" operator and setlink() function

This is my code
import java.util.*;
class node{
public int data;
public node link;
public node()
{
data = 0;
link = null;
}
public node(int d, node l)
{
data = d;
link = l;
}
void setlink(node n)
{
link = n;
}
void setdata(int dat)
{
data = dat;
}
int showdata()
{
return data;
}
node showlink()
{
return link;
}
}
class stack{
node top;
int size;
stack()
{
top = null;
size = 0;
}
void push()
{
node npt = new node();
size++;
System.out.println("Enter the value you want to enter :");
Scanner sc = new Scanner(System.in);
int val;
val = sc.nextInt();
npt.setdata(val);
if( top == null )
{
top = npt;
}
else
{
npt.setlink(top);
top = npt;
}
}
void pop()
{
node npt = top;
top = npt.showlink();
size--;
}
void showstack()
{
node nptr = top;
int i = 1;
while( nptr != null )
{
System.out.println("Data at position "+ i + " is : " + nptr.showdata());
i++;
nptr = nptr.showlink();
}
}
}
class stacked{
public static void main(String args[])
{
stack obj = new stack();
int temp = 0;
while( temp != 1 )
{
System.out.println("-- Enter 1 to exit -- 2 to push -- 3 to pop -- 4 to show Stack --");
Scanner sc = new Scanner(System.in);
temp = sc.nextInt();
if(temp == 1)
{
break;
}
switch(temp)
{
case 2: obj.push();
break;
case 3: obj.pop();
break;
case 4: obj.showstack();
break;
}
temp++;
}
}
}
My question is in the function void push() in class stack what is the difference between "=" operator and setlink() function.
I mean why cannot we write npt = top; instead of npt.setlink(top); ?
What does "=" do and how is the referencing done?
Thanks

Linked List search method

I am practicing build a doubly linked list contains string value.
In find method, I have a NullPointer Exception
here is my code.
package LinkedList;
package LinkedList;
public class LinkedList {
// 노드 클래스
class Node {
String value;
Node prev;
Node next;
Node(String v, Node p, Node s) {
value = v;
prev = p;
next = s;
}
public String getValue() {
return value;
}
public Node getPrev() {
return prev;
}
public Node getNext() {
return next;
}
public void setPrev(Node p) {
prev = p;
}
public void setNext(Node n) {
next = n;
}
}
Node head;
Node tail;
int size = 0;
public LinkedList() {
head = new Node(null, null, null);
tail = new Node(null, head, null);
head.setNext(tail);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public String first() {
if (isEmpty()) {
return null;
}
return head.getNext().getValue();
}
public String last() {
if (isEmpty()) {
return null;
}
return tail.getPrev().getValue();
}
public void addFirst(String value) {
addBetween(value, head, head.getNext());
}
public void addLast(String value) {
addBetween(value, tail.getPrev(), tail);
}
public void addBetween(String v, Node p, Node s) {
Node newNode = new Node(v, p, s);
p.setNext(newNode);
s.setPrev(newNode);
size++;
}
public String remove(Node node) {
Node p = node.getPrev();
Node s = node.getNext();
p.setNext(s);
s.setPrev(p);
size--;
return node.getValue();
}
public String removeFirst() {
if (isEmpty()) {
return null;
}
return remove(head.getNext());
}
public String removeLast() {
if (isEmpty()) {
return null;
}
return remove(tail.getPrev());
}
public void insert(String value) {
Node current = head;
// first
if (isEmpty()) {
addFirst(value);
} else {
// check
while (current.getNext() != tail || current.getValue().compareTo(value) > 0) {
current = current.getNext();
}
// last
if (current.getNext() == tail) {
addLast(value);
} else // between
{
addBetween(value, current.getNext(), current);
}
}
}
/* !!!!!!!!!!!!!! ERORR !!!!!!!!!!!! */
public void find(String value) {
Node current = head.getNext();
while ((current != null) || !(current.getValue().equals(value)))
current = current.getNext();
if (current.getValue().equals(value)) {
System.out.println("found " + value);
} else {
System.out.println("Not found " + value);
}
}
// • Traverse the list forwards and print
// 순회
public void fowardTraverse() {
Node current = head.getNext();
System.out.print(current.getValue());
while (current.getNext() != tail) {
current = current.getNext();
System.out.print(" -> " + current.getValue());
}
}
// • Traverse the list backwards and print
// 뒤로 순회
public void backwardTraverse() {
Node current = tail.getPrev();
System.out.print(current.getValue());
while (current.getPrev() != head) {
current = current.getPrev();
System.out.print(" -> " + current.getValue());
}
}
// • Delete a node from the list
// 지우기
public String delete(String value) {
return value;
}
// • Delete/destroy the list
// 파괴하기
public void destroy() {
}
public static void main(String[] args) {
// TODO Auto-generated method stubs
LinkedList a = new LinkedList();
a.insert("a");
a.insert("b");
a.insert("c");
a.insert("d");
a.insert("e");
a.insert("f");
a.insert("g");
a.insert("h");
a.insert("i");
// a.fowardTraverse();
a.find("a");
}
I don't understand why I get a nullpointException at the line,
It suppose to put a node contains a.
Make sure you check for Non-NULL before dereferencing:
Node current = head.getNext();
and
if (current.getValue().equals(value)) {
to be replaced by
Node current;
if(head != NULL) current = head.getNext();
and
if (current != NULL && current.getValue().equals(value)) {
Because your Head is empty...(No pun intended)
before Addfirst calling..your structure:
head=[null,null,tail],tail=[null,head,null];
you are sending ("a",head,tail)
and your storing it in new node making it a structure like:
head=[null,null,newNode]==>newNode["a",head,tail]==>tail[null,newNode,null]
So search will compare null to a (in find) giving you the error .....
---Edit 1:
#JanghyupLee, My Bad, Didn't do a closer look on find method...however , I found that in condition of "if" you are using condition
current != null || ......
After first line that is ( current=head.next)..current becomes not null..
which is causing the condition in while to ignore the right part of '||' (short circuit) until current has a value of null...
Once the current becomes null then it goes for the next statement to check for value..causing null pointer exception

Resources