import java.util.*; // doubly linked list, uses header and trailer sentinels. public class DList { private DNode header, trailer; private int size; public DList() { size = 0; header = new DNode(null, null, null); trailer = new DNode(null, header , null); header.setNext(trailer); } public int size() {return size;} public boolean isEmpty() {return size == 0;} public DNode getFirst() { if (isEmpty()) throw new RuntimeException("Empty"); return header.getNext(); } public DNode getLast() { if (isEmpty()) throw new RuntimeException("Empty"); return trailer.getPrev(); } public DNode getNext(DNode v) { DNode ans = v.getNext(); if (ans == null) throw new RuntimeException("No such node"); return ans; } public DNode getPrev(DNode v) { DNode ans = v.getPrev(); if (ans == null) throw new RuntimeException("No such node"); return ans; } public void addBefore(Object d, DNode v) { DNode u = getPrev(v); // throws if illegal DNode x = new DNode(d, u, v); u.setNext(x); v.setPrev(x); size ++; } public void addAfter(Object d, DNode v) { DNode w = getNext(v); // throws if illegal DNode x = new DNode(d, v, w); v.setNext(x); w.setPrev(x); size ++; } public void addFirst(Object d) { addAfter(d, header); } public void addLast(Object d) { addBefore(d, trailer); } public Object remove(DNode v) { if (v == header || v == trailer) throw new RuntimeException("Sentinel"); DNode u = v.getPrev(); DNode w = v.getNext(); w.setPrev(u); u.setNext(w); size --; return v.getData(); } // LinkedList testing methods: public String toString() { String ans = ""; DNode n = header; ans += "(H)<-->"; do { n = n.getNext(); if (n == trailer) ans += "(T)"; else ans += (n.getData() + "<-->"); } while (n != trailer); return ans; } public static void main(String args[]) { DList l = new DList(); DNode d = null; boolean done = false; while (!done) { try { Scanner s = new Scanner(System.in); System.out.print( l + " "); if (d != null && d.getData() != null) System.out.print( " ^^ " + d.getData()); System.out.println("\ncmds are F L B A R + - Q: >>"); String cmd = s.next(); String entry = null; char command = cmd.charAt(0); if (command == 'F' || command == 'L' || command == 'B' || command == 'A') entry = s.next(); switch (cmd.charAt(0)) { case 'Q': done = true; break; case 'R': DNode e = d.getNext(); l.remove(d); d = e; break; case '+': d = l.getNext(d); break; case '-': d = l.getPrev(d); break; case 'F': l.addFirst(entry); d = l.getFirst(); break; case 'L': l.addLast(entry); d = l.getLast();break; case 'B': l.addBefore(entry, d); d = l.getPrev(d); break; case 'A': l.addAfter(entry, d); d = l.getNext(d); break; } } catch (Exception e) { System.out.println("Error " + e.toString()); } } } } class DNode { private Object data; private DNode prev, next; public DNode(Object d, DNode p, DNode n) { data = d; next = n; prev = p; } public Object getData() { return data; } public DNode getNext() { return next; } public DNode getPrev() { return prev; } public void setData(Object d) { data = d; } public void setNext(DNode n) { next = n; } public void setPrev(DNode p) { prev = p; } }