package Assignment4;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.util.*;
import java.io.*;
public class DoublyLinkedList<T>
{
private class Node<T>
{
private T data;
private Node<T> next;
private Node<T> previous;
public Node(T data,Node<T> next, Node<T> previous)
{
this.data = data;
this.next = next;
this.previous=previous;
}
public T getData()
{
return data;
}
public Node<T> getNext()
{
return next;
}
public Node<T> getPrevious()
{
return previous;
}
public void setNext(Node<T> next)
{
this.next = next;
}
public void setPrevious(Node<T> previous)
{
this.previous = previous;
}
}
private Node<T> head;//head of the linked list
private Node<T> tail; // tail of linked list
private int size;
private ImageIcon icon;
private Icon icon2;
public DoublyLinkedList()
{
head = null;
tail = null;
size = 0;
icon = new ImageIcon("doh3.jpg");
}
public String toString()
{
String str = "[";
Node<T> curr;
for (curr=head;curr!=null;curr = curr.getNext())
{
str = str + curr.getData();
if (curr.getNext()!=null)
str = str + " ";
}
str = str + "]";
return str;
// can this stay the same? I did copy some of this from the SinglyLinkedList code we got in class. I don't know exactly how to edit it to make it a DoublyLinkedList.
// i.e. a list that refers to two things, next and previous, rather than just next. It makes adding something at the end or close to the end more efficient than a SinglyLinkedList.
}
public void addFirst(T data)
{
// Node<T> newnode = new Node<T>(data,head, null);
// Node<T> newnode;
// newnode = head;
//head = newnode.getPrevious(); // sets the head
// newnode = head.next; // puts old head after new head
// size++;
if (size == 0)
{
Node<T> newNode = new Node<T>(data,head,tail);
head.setPrevious(newNode);
head = newNode;
}
Node<T> newNode = new Node<T>(data,head,null);
head.setPrevious(newNode);
head = newNode;
newNode = head;
head = head.getNext();
size++;
}
public void removeFirst()
{
if (size == 0)
{
JOptionPane pane = new JOptionPane();
pane.setIcon(icon);
pane.showMessageDialog(null, "Cannot remove from an empty list!", "Invalid removal", JOptionPane.ERROR_MESSAGE);
pane.setMessageType(JOptionPane.ERROR_MESSAGE);
return;
}
Node<T> current = head;
head = head.getNext(); //move head to the next element
current.setNext(null);
}
public void addLast(T data)
{
//If there are no elements, use the addFirst method
if (tail == null)
{
addFirst(data);
return;
}
/* Create the new Node from the data. Set next to null
* because this will be the last element and will not
* have a next. Set previous to tail because tail has
* not been changed yet and is currently referencing
* that element that will be directly before this element
*/
Node<T> newNode = new Node(data,null,tail);
/* Since the tail variable still references the element
* directly before the new element, we can set that node's
* next to our new element.
*/
tail.setNext(newNode);
//Set tail to our new Node
tail = newNode;
//Increment size
size++;
}
public void add(int index,T data)
{
int i;
if (index>size)
return;
if (index < 0)
return;
if (head==null)
{
addFirst(data);
return;
}
if (index == size)
{
addLast(data);
return;
}
//step 1
Node<T> current;
current = head;
for (i=0;i<index-1;i++)
{
current = current.getNext();
}
//current now refers to object immediately before new node
//step 2
Node<T> newnode = new Node<T>(data,current.getNext(), current.getPrevious());
//step 3
current.setNext(newnode);
size++;
}
public void remove(int index)
{
if ((index<0) || (index>=size))
{
JOptionPane.showMessageDialog(null, "You cannot remove an out-of-bounds value!", "Invalid removal", JOptionPane.ERROR_MESSAGE);
return;
}
Node<T> current,previous2;
current = head;
previous2 = null;
for (int i=0;i<index;i++)
{
previous2 = current;
current = current.getNext();
}
if (index!=0)
previous2.setNext(current.getNext());
else
{
head = head.getNext();
}
size--;
}
public T get(int i)
{
if (i < 0 || i >= size)
return null;
// How do I get it to return the data at i?
}
public T front()
{
if (head == null)
return null;
return(get(0));
}
public T back()
{
if (tail == null)
return null;
return(get(size - 1));
}
public String printAlternate()
{
/*
This method returns a string that has
the data in the following fashion (assume for this example that the list stores String objects)
If the list is currently [amit is now here], it will return a string “[amit here is now]”
If the list is currently [amit is now currently here], it will return a string “[amit here is currently now]”
*/
}
}