/** * */ package dataStructures; /** * @author Ricardo Gaspar Nr. 35277 * @author Hugo Antnio Nr. 34334 Turno P2 Docente Vasco Amaral */ public class OrderedDoublyLL, V> implements OrderedDictionary { private static final long serialVersionUID = 1L; // Node at the head of the list. protected DListNode> head; // Node at the tail of the list. protected DListNode> tail; // Number of elements in the list. protected int currentSize; /** * Construtor da OrderedDoublyLL. Inicializa a cabea, cauda e o tamanho da * lista. */ public OrderedDoublyLL() { head = null; tail = null; currentSize = 0; } @Override public boolean isEmpty() { return currentSize == 0; } @Override public int size() { return currentSize; } @Override public V find(K key) { V value = null; if (!this.isEmpty()) { DListNode> node = findNode(key); if (node != null && node.getElement().getKey().compareTo(key) == 0) value = node.getElement().getValue(); } return value; } @Override public V insert(K key, V value) { Entry newEntry = new EntryClass(key, value); if (this.isEmpty()) { addFirst(newEntry); return null; } DListNode> nodeFound = findNode(key); if (nodeFound != null) { Entry entryFound = nodeFound.getElement(); if (entryFound.getKey().compareTo(key) == 0) { V resultValue = entryFound.getValue(); nodeFound.setElement(newEntry); return resultValue; } else if (entryFound.getKey().compareTo(key) > 0) { if (nodeFound == head) addFirst(newEntry); else addMiddle(newEntry, nodeFound); return null; } } addLast(newEntry); return null; } @Override public V remove(K key) { if (this.isEmpty()) return null; DListNode> nodeFound = findNode(key); if (nodeFound != null) { Entry entryFound = nodeFound.getElement(); if (entryFound.getKey().compareTo(key) == 0) { V resultValue = entryFound.getValue(); if (nodeFound == head) removeFirstNode(); else if (nodeFound == tail) removeLastNode(); else removeMiddleNode(nodeFound); return resultValue; } } return null; } @Override public Iterator> iterator() { return new DoublyLLIterator>(head, tail); } @Override public Entry minEntry() throws EmptyDictionaryException { if (this.isEmpty()) return null; return head.getElement(); } @Override public Entry maxEntry() throws EmptyDictionaryException { if (this.isEmpty()) return null; return tail.getElement(); } /** * Mtodos Auxiliares */ /** * Devolve o um n da lista que contenha a chave dada. Caso no exista * devolve o primeiro cuja chave maior. Devolve null se * chegar ao fim da lista sem encontrar o n pretendido. * * @param key * Chave do elemento a procurar. * @return Devolve um DListNode< Entry< K,V > > com a chave ( * key) dada, caso exista. Caso no exista: - * DListNode< Entry< K,V > > do primeiro n cuja chave * maior que key. - null quando * key maior que todas as chaves existentes. */ protected DListNode> findNode(K key) { DListNode> node = head; while (node != null && node.getElement().getKey().compareTo(key) < 0) node = node.getNext(); return node; } /** * Adiciona um elemento cabea da lista. * * @param element * Elemento a inserir. */ protected void addFirst(Entry element) { DListNode> newNode = new DListNode>(element, null, head); if (this.isEmpty()) tail = newNode; else head.setPrevious(newNode); head = newNode; currentSize++; } /** * Adiciona um elemento cauda da lista. * * @param element * Elemento a inserir. */ protected void addLast(Entry element) { DListNode> newNode = new DListNode>(element, tail, null); if (this.isEmpty()) head = newNode; else tail.setNext(newNode); tail = newNode; currentSize++; } /** * Adiciona um elemento no meio da lista (entre dois ns). O elemento * adicionado antes de um dado n. * * @param element * Elemento a inserir. * @param node * N seguinte ao elemento. */ protected void addMiddle(Entry element, DListNode> node) { DListNode> PrevNode = node.getPrevious(); DListNode> newNode = new DListNode>(element, PrevNode, node); PrevNode.setNext(newNode); node.setPrevious(newNode); currentSize++; } /** * Remove a cabea da lista. * * @Pre: A lista no est vazia */ protected void removeFirstNode() { head = head.getNext(); if (head == null) tail = null; else head.setPrevious(null); currentSize--; } /** * Remove a cauda da lista. * * @Pre: A lista no est vazia */ protected void removeLastNode() { tail = tail.getPrevious(); if (tail == null) head = null; else tail.setNext(null); currentSize--; } /** * Remove um dado n que se encontra a meio da lista. * * @Pre: O n no cabea nem cauda da lista. */ protected void removeMiddleNode(DListNode> node) { DListNode> prevNode = node.getPrevious(); DListNode> nextNode = node.getNext(); prevNode.setNext(nextNode); nextNode.setPrevious(prevNode); currentSize--; } }