Can I use class methods inside factory constructor via Dart - dart

I have the below code that is creating the PriortyQueue structure using Dart. But since I cannot use heapify function inside the Constructor or factory constructor I cannot initialize PQ with an existing set of List. Can somebody guide me and show me how I can use heapify while creating PQ instance so I can initialize it with an existing List? Also If you have any other suggestions against doing something like this please also help me as well. thank you
class PriorityQueue<T extends Comparable<T>> {
List<T?> _tree;
PriorityQueue._(List<T?> tree) : _tree = tree;
factory PriorityQueue([List<T>? array]) {
List<T?> newArray = [null, ...array ?? []];
// ignore: todo
//TODO: missing heapify
return PriorityQueue._(newArray);
}
void insert(T node) {
_tree.add(node);
_swim(_tree.length - 1);
}
T getTop() {
_swap(1, _tree.length - 1);
T top = _tree.removeLast() as T;
_sink(1);
return top;
}
List<T> _heapify(List<T> array) {
int sinkNodeIndex = (array.length - 1) ~/ 2;
while (sinkNodeIndex >= 1) {
_sink(sinkNodeIndex);
sinkNodeIndex--;
}
}
void _sink(int nodeIndex) {
int leftChildIndex = nodeIndex * 2;
int rightChildIndex = leftChildIndex + 1;
int minNodeIndex = leftChildIndex;
// index can be unreachable
T? leftChild =
leftChildIndex >= _tree.length ? null : _tree[leftChildIndex];
T? rightChild =
rightChildIndex >= _tree.length ? null : _tree[rightChildIndex];
if (leftChild == null) {
return;
}
if (rightChild != null && leftChild.compareTo(rightChild) > 0) {
minNodeIndex = rightChildIndex;
}
if ((_tree[minNodeIndex] as T).compareTo(_tree[nodeIndex] as T) < 0) {
_swap(nodeIndex, minNodeIndex);
_sink(minNodeIndex);
}
}
void _swim(int nodeIndex) {
if (nodeIndex <= 1) return;
int parentIndex = nodeIndex ~/ 2;
if ((_tree[nodeIndex] as T).compareTo(_tree[parentIndex] as T) < 0) {
_swap(nodeIndex, parentIndex);
_swim(parentIndex);
}
}
void _swap(int i, int j) {
T temp = _tree[i] as T;
_tree[i] = _tree[j];
_tree[j] = temp;
}
#override
String toString() {
return _tree.toString();
}
}

I would make all the helper functions. _heapify, _sink/_swim, even _swap, be static functions which take the list as argument.
Then you can use them from anywhere, including inside the factory constructor.
Alternatively, you can change the constructor to returning:
return PriorityQueue._(newArray).._heapify();
This creates the PriorityQueue object, and then calls the _heapify method on it, before returning the value.
(I'd also make _tree have type List<T> and not insert the extra null at the beginning. It's more efficient to add/subtract 1 from indices than it is to cast to T.)

I ended up doing like Irn's first suggestion. But when I do functions static they lost Type of the class so I needed to specify for each function. Also, making List<T?> instead of List ended up with me fighting against the compiler.
class PriorityQueue<T extends Comparable<T>> {
List<T?> _tree;
PriorityQueue._(List<T?> tree) : _tree = tree;
factory PriorityQueue([List<T>? array]) {
List<T?> newArray = [null, ...array ?? []];
_heapify(newArray);
return PriorityQueue._(newArray);
}
bool get isNotEmpty {
return _tree.isNotEmpty;
}
void insert(T node) {
_tree.add(node);
_swim(_tree, _tree.length - 1);
}
void insertMultiple(List<T> array) {
for (var element in array) {
insert(element);
}
}
T? removeTop() {
if (_tree.length == 1) return null;
_swap(_tree, 1, _tree.length - 1);
T top = _tree.removeLast() as T;
_sink(_tree, 1);
return top;
}
void removeAll() {
_tree = [null];
}
static void _heapify<T extends Comparable<T>>(List<T?> array) {
int sinkNodeIndex = (array.length - 1) ~/ 2;
while (sinkNodeIndex >= 1) {
_sink(array, sinkNodeIndex);
sinkNodeIndex--;
}
}
static void _sink<T extends Comparable<T>>(List<T?> tree, int nodeIndex) {
int leftChildIndex = nodeIndex * 2;
int rightChildIndex = leftChildIndex + 1;
int minNodeIndex = leftChildIndex;
T? leftChild = leftChildIndex >= tree.length ? null : tree[leftChildIndex];
T? rightChild =
rightChildIndex >= tree.length ? null : tree[rightChildIndex];
if (leftChild == null) {
return;
}
if (rightChild != null && leftChild.compareTo(rightChild) > 0) {
minNodeIndex = rightChildIndex;
}
if ((tree[minNodeIndex] as T).compareTo(tree[nodeIndex] as T) < 0) {
_swap(tree, nodeIndex, minNodeIndex);
_sink(tree, minNodeIndex);
}
}
static void _swim<T extends Comparable<T>>(List<T?> tree, int nodeIndex) {
if (nodeIndex <= 1) return;
int parentIndex = nodeIndex ~/ 2;
if ((tree[nodeIndex] as T).compareTo(tree[parentIndex] as T) < 0) {
_swap(tree, nodeIndex, parentIndex);
_swim(tree, parentIndex);
}
}
static void _swap<T extends Comparable<T>>(List<T?> tree, int i, int j) {
T temp = tree[i] as T;
tree[i] = tree[j];
tree[j] = temp;
}
#override
String toString() {
return _tree.toString();
}
}

Related

dynamic programming grid problem approach solving using BFS

We have an NxM grid, grid have one element named Bob. Bob can travel diagonally blocks only. The grid has some blocked blocks on which Bob can not travel. Write a function that returns on how many possible positions Bob can move. Solve this problem using BFS and submit the executable code in any programming language. In the following image example, Bob's positioning is at 9,3, and it can visit the places where Y is marked; hence your method should return 30.
Anybody any pseudocode or approach on how to solve this using BFS
Following solution is modified version of solution given by ( https://stackoverflow.com/users/10987431/dominicm00 ) on problem ( Using BFS to find number of possible paths for an object on a grid )
Map.java:
import java.awt.*;
public class Map {
public final int width;
public final int height;
private final Cell[][] cells;
private final Move[] moves;
private Point startPoint;
public Map(int[][] mapData) {
this.width = mapData[0].length;
this.height = mapData.length;
cells = new Cell[height][width];
// define valid movements
moves = new Move[]{
new Move(1, 1),
new Move(-1, 1),
new Move(1, -1),
new Move(-1, -1)
};
generateCells(mapData);
}
public Point getStartPoint() {
return startPoint;
}
public void setStartPoint(Point p) {
if (!isValidLocation(p)) throw new IllegalArgumentException("Invalid point");
startPoint.setLocation(p);
}
public Cell getStartCell() {
return getCellAtPoint(getStartPoint());
}
public Cell getCellAtPoint(Point p) {
if (!isValidLocation(p)) throw new IllegalArgumentException("Invalid point");
return cells[p.y][p.x];
}
private void generateCells(int[][] mapData) {
boolean foundStart = false;
for (int i = 0; i < mapData.length; i++) {
for (int j = 0; j < mapData[i].length; j++) {
/*
0 = empty space
1 = wall
2 = starting point
*/
if (mapData[i][j] == 2) {
if (foundStart) throw new IllegalArgumentException("Cannot have more than one start position");
foundStart = true;
startPoint = new Point(j, i);
} else if (mapData[i][j] != 0 && mapData[i][j] != 1) {
throw new IllegalArgumentException("Map input data must contain only 0, 1, 2");
}
cells[i][j] = new Cell(j, i, mapData[i][j] == 1);
}
}
if (!foundStart) throw new IllegalArgumentException("No start point in map data");
// Add all cells adjacencies based on up, down, left, right movement
generateAdj();
}
private void generateAdj() {
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
for (Move move : moves) {
Point p2 = new Point(j + move.getX(), i + move.getY());
if (isValidLocation(p2)) {
cells[i][j].addAdjCell(cells[p2.y][p2.x]);
}
}
}
}
}
private boolean isValidLocation(Point p) {
if (p == null) throw new IllegalArgumentException("Point cannot be null");
return (p.x >= 0 && p.y >= 0) && (p.y < cells.length && p.x < cells[p.y].length);
}
private class Move {
private int x;
private int y;
public Move(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}}
Cell.java:
import java.util.LinkedList;
public class Cell {
public final int x;
public final int y;
public final boolean isWall;
private final LinkedList<Cell> adjCells;
public Cell(int x, int y, boolean isWall) {
if (x < 0 || y < 0) throw new IllegalArgumentException("x, y must be greater than 0");
this.x = x;
this.y = y;
this.isWall = isWall;
adjCells = new LinkedList<>();
}
public void addAdjCell(Cell c) {
if (c == null) throw new IllegalArgumentException("Cell cannot be null");
adjCells.add(c);
}
public LinkedList<Cell> getAdjCells() {
return adjCells;
}}
MapHelper.java:
class MapHelper {
public static int countReachableCells(Map map) {
if (map == null) throw new IllegalArgumentException("Arguments cannot be null");
boolean[][] visited = new boolean[map.height][map.width];
// subtract one to exclude starting point
return dfs(map.getStartCell(), visited) - 1;
}
private static int dfs(Cell currentCell, boolean[][] visited) {
visited[currentCell.y][currentCell.x] = true;
int touchedCells = 0;
for (Cell adjCell : currentCell.getAdjCells()) {
if (!adjCell.isWall && !visited[adjCell.y][adjCell.x]) {
touchedCells += dfs(adjCell, visited);
}
}
return ++touchedCells;
}}
Grid.java:
public class Grid{
public static void main(String args[]){
int[][] gridData = {
{0,0,0,0,0,0,0,0},
{0,1,0,0,0,1,0,0},
{0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,1,0,0,1,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0},
{0,0,1,0,0,1,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,2,1,0,0,0}}; //2 is bobs position, 1 is blocked, 0 can be visited
Map grid = new Map(gridData);
MapHelper solution = new MapHelper();
System.out.println(solution.countReachableCells(grid));
}}
For original answer of similar problem visit (Using BFS to find number of possible paths for an object on a grid) for original answer.

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.

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

Double 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;
}
}

Resources