Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.45 KB | None | 0 0
  1. /*
  2.  * To change this license header, choose License Headers in Project Properties.
  3.  * To change this template file, choose Tools | Templates
  4.  * and open the template in the editor.
  5.  */
  6. package esinf_1160676_1161154;
  7.  
  8. import com.sun.javafx.geom.Curve;
  9. import java.util.Iterator;
  10. import java.util.ListIterator;
  11. import java.util.NoSuchElementException;
  12. import java.util.ConcurrentModificationException;
  13. import java.util.Objects;
  14.  
  15. /**
  16.  *
  17.  * @author DEI-ISEP
  18.  * @param <E> Generic list element type
  19.  */
  20. public class DoublyLinkedList<E> implements Iterable<E>, Cloneable {
  21.  
  22. // instance variables of the DoublyLinkedList
  23.     private final Node<E> header;     // header sentinel
  24.     private final Node<E> trailer;    // trailer sentinel
  25.     private int size = 0;       // number of elements in the list
  26.     private int modCount = 0;   // number of modifications to the list (adds or removes)
  27.  
  28.     /**
  29.      * Creates both elements which act as sentinels
  30.      */
  31.     public DoublyLinkedList() {
  32.  
  33.         header = new Node<>(null, null, null);      // create header
  34.         trailer = new Node<>(null, header, null);   // trailer is preceded by header
  35.         header.setNext(trailer);                    // header is followed by trailer
  36.     }
  37.  
  38.     /**
  39.      * Returns the number of elements in the linked list
  40.      *
  41.      * @return the number of elements in the linked list
  42.      */
  43.     public int size() {
  44.         return size;
  45.     }
  46.  
  47.     /**
  48.      * Checks if the list is empty
  49.      *
  50.      * @return true if the list is empty, and false otherwise
  51.      */
  52.     public boolean isEmpty() {
  53.         return size == 0;
  54.     }
  55.  
  56.     /**
  57.      * Returns (but does not remove) the first element in the list
  58.      *
  59.      * @return the first element of the list
  60.      */
  61.     public E first() {
  62.         return header.getNext().getElement();
  63.     }
  64.  
  65.     /**
  66.      * Returns (but does not remove) the last element in the list
  67.      *
  68.      * @return the last element of the list
  69.      */
  70.     public E last() {
  71.         return trailer.getPrev().getElement();
  72.     }
  73.  
  74.     @Override
  75.     public String toString() {
  76.        ListIterator iterator=this.listIterator();
  77.        String returnable="";
  78.         while (iterator.hasNext()) {
  79.             returnable+="\n"+iterator.next().toString();
  80.         }
  81.         return returnable;
  82.     }
  83.    
  84.  
  85. // public update methods
  86.     /**
  87.      * Adds an element e to the front of the list
  88.      *
  89.      * @param e element to be added to the front of the list
  90.      */
  91.     public void addFirst(E e) {
  92.         // place just after the header
  93.         addBetween(e, header, header.getNext());
  94.     }
  95.  
  96.     /**
  97.      * Adds an element e to the end of the list
  98.      *
  99.      * @param e element to be added to the end of the list
  100.      */
  101.     public void addLast(E e) {
  102.         // place just before the trailer
  103.         addBetween(e, trailer.getPrev(), trailer);
  104.     }
  105.  
  106.     /**
  107.      * Removes and returns the first element of the list
  108.      *
  109.      * @return the first element of the list
  110.      */
  111.     public E removeFirst() {
  112.         return remove(header.getNext());
  113.     }
  114.  
  115.     /**
  116.      * Removes and returns the last element of the list
  117.      *
  118.      * @return the last element of the list
  119.      */
  120.     public E removeLast() {
  121.         return remove(trailer.getPrev());
  122.     }
  123.  
  124. // private update methods
  125.     /**
  126.      * Adds an element e to the linked list between the two given nodes.
  127.      */
  128.     private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
  129.         Node node = new Node<>(e, predecessor, successor);
  130.         node.setElement(e);
  131.         node.setPrev(predecessor);
  132.         predecessor.setNext(node);
  133.         node.setNext(successor);
  134.         successor.setPrev(node);
  135.         size++;
  136.         modCount++;
  137.     }
  138.  
  139.     /**
  140.      * Removes a given node from the list and returns its content.
  141.      */
  142.     private E remove(Node<E> node) {
  143.         if (size != 0) {
  144.             Node predecessor = node.getPrev();
  145.             Node successor = node.getNext();
  146.             predecessor.setNext(successor);
  147.             successor.setPrev(predecessor);
  148.             node.setNext(null);
  149.             node.setPrev(null);
  150.             size--;
  151.             modCount++;
  152.             return node.getElement();
  153.         }
  154.         return null;
  155.     }
  156. // Overriden methods
  157.  
  158.     @Override
  159.     public boolean equals(Object obj) {
  160.         if (!(obj instanceof DoublyLinkedList)) {
  161.             return false;
  162.         }
  163.  
  164.         DoublyLinkedList<E> other = (DoublyLinkedList<E>) obj;
  165.  
  166.         if (this.size() != other.size()) {
  167.             return false;
  168.         }
  169.  
  170.         Node<E> thisNode = header;
  171.         Node<E> otherNode = other.header;
  172.  
  173.         while (thisNode.getNext() != trailer) {
  174.             thisNode = thisNode.getNext();
  175.             otherNode = otherNode.getNext();
  176.             if (!(thisNode.getElement().equals(otherNode.getElement()))) {
  177.                 return false;
  178.             }
  179.         }
  180.         return true;
  181.     }
  182.  
  183.     @Override
  184.     public Object clone() throws CloneNotSupportedException {
  185.  
  186.         DoublyLinkedList<E> other = new DoublyLinkedList<>();
  187.         if (size > 0) {
  188.             Node<E> newNode = header.getNext();
  189.             for (int i = 0; i < size; i++) {
  190.                 other.addLast(newNode.getElement());
  191.                 newNode = newNode.getNext();
  192.             }
  193.         }
  194.         return other;
  195.     }
  196.  
  197.     void removeFirst(int i) {
  198.         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  199.     }
  200.  
  201. //---------------- nested DoublyLinkedListIterator class ----------------        
  202.     private class DoublyLinkedListIterator implements ListIterator<E> {
  203.  
  204.         private DoublyLinkedList.Node<E> nextNode, prevNode, lastReturnedNode; // node that will be returned using next and prev respectively
  205.         private int nextIndex;  // Index of the next element
  206.         private int expectedModCount;  // Expected number of modifications = modCount;
  207.  
  208.         public DoublyLinkedListIterator() {
  209.             this.prevNode = header;
  210.             this.nextNode = header.getNext();
  211.             lastReturnedNode = null;
  212.             nextIndex = 0;
  213.             expectedModCount = modCount;
  214.         }
  215.  
  216.         final void checkForComodification() {  // invalidate iterator on list modification outside the iterator
  217.             if (modCount != expectedModCount) {
  218.                 throw new ConcurrentModificationException();
  219.             }
  220.         }
  221.  
  222.         @Override
  223.         public boolean hasNext() {
  224.             return nextNode.getElement() != null;
  225.         }
  226.  
  227.         @Override
  228.         public E next() throws NoSuchElementException {
  229.             checkForComodification();
  230.             if (!hasNext()) {
  231.                 throw new NoSuchElementException("End of list reached.");
  232.             }
  233.             lastReturnedNode = nextNode;
  234.             nextNode = lastReturnedNode.getNext();
  235.             prevNode = lastReturnedNode;
  236.             nextIndex++;
  237.             return lastReturnedNode.getElement();
  238.         }
  239.  
  240.         @Override
  241.         public boolean hasPrevious() {
  242.             return prevNode.getElement() != null;
  243.         }
  244.  
  245.         @Override
  246.         public E previous() throws NoSuchElementException {
  247.             checkForComodification();
  248.             if (!hasPrevious()) {
  249.                 throw new NoSuchElementException("Beggining of list reached.");
  250.             }
  251.             lastReturnedNode = prevNode;
  252.             nextNode = lastReturnedNode;
  253.             prevNode = lastReturnedNode.getPrev();
  254.             nextIndex--;
  255.             return lastReturnedNode.getElement();
  256.         }
  257.  
  258.         @Override
  259.         public int nextIndex() {
  260.             return nextIndex;
  261.         }
  262.  
  263.         @Override
  264.         public int previousIndex() {
  265.             return nextIndex - 1;
  266.         }
  267.  
  268.         @Override
  269.         public void remove() throws NoSuchElementException {
  270.             checkForComodification();
  271.             if (hasNext() || hasPrevious()) {
  272.                 if (lastReturnedNode == null) {
  273.                     throw new NoSuchElementException();
  274.                 }
  275.                 if (lastReturnedNode == nextNode) {
  276.                     nextIndex--;
  277.                 }
  278.                 DoublyLinkedList.this.remove(lastReturnedNode);
  279.                 lastReturnedNode = lastReturnedNode.getPrev();
  280.                 expectedModCount++;
  281.             }
  282.         }
  283.  
  284.         @Override
  285.         public void set(E e) throws NoSuchElementException {
  286.             if (lastReturnedNode == null) {
  287.                 throw new NoSuchElementException();
  288.             }
  289.             checkForComodification();
  290.             lastReturnedNode.setElement(e);
  291.         }
  292.  
  293.         @Override
  294.         public void add(E e) {
  295.             checkForComodification();
  296.             DoublyLinkedList.this.addBetween(e, prevNode, nextNode);
  297.             prevNode = prevNode.getNext();
  298.             lastReturnedNode = prevNode;
  299.             nextIndex++;
  300.             expectedModCount++;
  301.         }
  302.  
  303.     }    //----------- end of inner DoublyLinkedListIterator class ----------
  304.  
  305. //---------------- Iterable implementation ----------------
  306.     @Override
  307.     public Iterator<E> iterator() {
  308.         return new DoublyLinkedListIterator();
  309.     }
  310.  
  311.     public ListIterator<E> listIterator() {
  312.         return new DoublyLinkedListIterator();
  313.     }
  314.  
  315. //---------------- nested Node class ----------------
  316.     private static class Node<E> {
  317.  
  318.         private E element;      // reference to the element stored at this node
  319.         private Node<E> prev;   // reference to the previous node in the list
  320.         private Node<E> next;   // reference to the subsequent node in the list
  321.  
  322.         public Node(E element, Node<E> prev, Node<E> next) {
  323.             this.element = element;
  324.             this.prev = prev;
  325.             this.next = next;
  326.         }
  327.  
  328.         public E getElement() {
  329.             return element;
  330.         }
  331.  
  332.         public Node<E> getPrev() {
  333.             return prev;
  334.         }
  335.  
  336.         public Node<E> getNext() {
  337.             return next;
  338.         }
  339.  
  340.         public void setElement(E element) { // Not on the original interface. Added due to list iterator implementation
  341.             this.element = element;
  342.         }
  343.  
  344.         public void setPrev(Node<E> prev) {
  345.             this.prev = prev;
  346.         }
  347.  
  348.         public void setNext(Node<E> next) {
  349.             this.next = next;
  350.         }
  351.     } //----------- end of nested Node class ----------
  352.  
  353. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement