initial commit
This commit is contained in:
10
.classpath
Executable file
10
.classpath
Executable file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
.project
Executable file
17
.project
Executable file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>AlgoritmiStruttureDati</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
12
.settings/org.eclipse.jdt.core.prefs
Executable file
12
.settings/org.eclipse.jdt.core.prefs
Executable file
@@ -0,0 +1,12 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
11
src/it/algoritmi/adt/CircularQueue.java
Normal file
11
src/it/algoritmi/adt/CircularQueue.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
public interface CircularQueue<E> extends Queue<E> {
|
||||
|
||||
/**
|
||||
* Sposta alla fine della coda il suo elemento iniziale.
|
||||
* Se la coda <20> vuota non fa niente.
|
||||
*/
|
||||
void rotate();
|
||||
|
||||
}
|
||||
33
src/it/algoritmi/adt/Deque.java
Normal file
33
src/it/algoritmi/adt/Deque.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
/**
|
||||
* Interfaccia che definisce una coda doppia: un contenitore di elementi con
|
||||
* inserimenti e rimozioni ai due estremi. Semplificata rispetto a java.util.Dequeue.
|
||||
*/
|
||||
public interface Deque<E> {
|
||||
|
||||
/** Restituisce il numero di elementi presenti nella coda doppia. */
|
||||
int size();
|
||||
|
||||
/** Verifica se la coda doppia <20> vuota. */
|
||||
boolean isEmpty();
|
||||
|
||||
/** Restituisce il primo elemento, senza toglierlo (null se la coda <20> vuota). */
|
||||
E first();
|
||||
|
||||
/** Restituisce l'ultimo elemento, senza toglierlo (null se la coda <20> vuota). */
|
||||
E last();
|
||||
|
||||
/** Inserisce un elemento all'inizio della coda doppia. */
|
||||
void addFirst(E e);
|
||||
|
||||
/** Inserisce un elemento alla fine della coda doppia. */
|
||||
void addLast(E e);
|
||||
|
||||
/** Elimina e restituisce il primo elemento della coda (null se <20> vuota). */
|
||||
E removeFirst();
|
||||
|
||||
/** Elimina e restituisce l'ultimo elemento della coda (null se <20> vuota). */
|
||||
E removeLast();
|
||||
|
||||
}
|
||||
24
src/it/algoritmi/adt/List.java
Normal file
24
src/it/algoritmi/adt/List.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
/** Una versione semplificata dell'interfaccia java.util.List. */
|
||||
public interface List<E> extends Iterable<E> {
|
||||
|
||||
/** Restituisce il numero di elementi presenti nella lista. */
|
||||
int size();
|
||||
|
||||
/** Restituisce true se e sole se la lista è vuota. */
|
||||
boolean isEmpty();
|
||||
|
||||
/** Restituisce l'elemento corristondente all'indice i, senza eliminarlo. */
|
||||
E get(int i) throws IndexOutOfBoundsException;
|
||||
|
||||
/** Sostituisce con e l'elemento di indice i; restituisce l'elemento sostituito. */
|
||||
E set(int i, E e) throws IndexOutOfBoundsException;
|
||||
|
||||
/** Inserisce e come elemento di indice i, spostando gli elementi successivi. */
|
||||
void add(int i, E e) throws IndexOutOfBoundsException;
|
||||
|
||||
/** Rimuove e restituisce l'elemento di indice i, spostando i successivi. */
|
||||
E remove(int i) throws IndexOutOfBoundsException;
|
||||
|
||||
}
|
||||
13
src/it/algoritmi/adt/Position.java
Normal file
13
src/it/algoritmi/adt/Position.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
public interface Position<E> {
|
||||
|
||||
/**
|
||||
* Restituisce l'elemento memorizzato in questa posizione.
|
||||
*
|
||||
* @return l'elemento memorizzato
|
||||
* @throws IllegalStateException se la posizione non è più valida
|
||||
*/
|
||||
E getElement() throws IllegalStateException;
|
||||
|
||||
}
|
||||
45
src/it/algoritmi/adt/PositionalList.java
Normal file
45
src/it/algoritmi/adt/PositionalList.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
/** L'interfaccia che definisce liste posizionali. */
|
||||
public interface PositionalList<E> extends Iterable<E> {
|
||||
|
||||
/** Restituisce il numero di elementi presenti nella lista. */
|
||||
int size();
|
||||
|
||||
/** Restituisce true se e solo se la lista è vuota. */
|
||||
boolean isEmpty();
|
||||
|
||||
/** Restituisce la prima Position della lista (o null se la lista è vuota). */
|
||||
Position<E> first();
|
||||
|
||||
/** Restituisce l'ultima Position della lista (o null se la lista è vuota). */
|
||||
Position<E> last();
|
||||
|
||||
/** Restituisce la Position che precede p (o null, se p è la prima). */
|
||||
Position<E> before(Position<E> position) throws IllegalArgumentException;
|
||||
|
||||
/** Restituisce la Position che segue p (o null, se p è l'ultima). */
|
||||
Position<E> after(Position<E> position) throws IllegalArgumentException;
|
||||
|
||||
/** Inserisce l'elemento e all'inizio della lista; ne restituisce la posizione. */
|
||||
Position<E> addFirst(E element);
|
||||
|
||||
/** Inserisce l'elemento e alla fine della lista; ne restituisce la posizione. */
|
||||
Position<E> addLast(E element);
|
||||
|
||||
/** Inserisce l'elemento e prima della Position p; ne restituisce la posizione. */
|
||||
Position<E> addBefore(Position<E> position, E element) throws IllegalArgumentException;
|
||||
|
||||
/** Inserisce l'elemento e dopo la Position p; ne restituisce la posizione. */
|
||||
Position<E> addAfter(Position<E> position, E element) throws IllegalArgumentException;
|
||||
|
||||
/** Sostituisce l'elemento nella Position p; restituisce l'elemento sostituito. */
|
||||
E set(Position<E> position, E element) throws IllegalArgumentException;
|
||||
|
||||
/** Elimina e restituisce l'elemento nella Position p; (poi p non è più valida). */
|
||||
E remove(Position<E> position) throws IllegalArgumentException;
|
||||
|
||||
/** Restituisce una rappresentazione iterabile delle posizioni dela lista. */
|
||||
public Iterable<Position<E>> positions();
|
||||
|
||||
}
|
||||
20
src/it/algoritmi/adt/Queue.java
Normal file
20
src/it/algoritmi/adt/Queue.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
public interface Queue<E> {
|
||||
|
||||
/** Restituisce il numero di elementi presenti nella coda. */
|
||||
public int size();
|
||||
|
||||
/** Verifica se la coda <20> vuota. */
|
||||
public boolean isEmpty();
|
||||
|
||||
/** Inserisce un elemento in fondo alla coda. */
|
||||
public void enqueue(E e);
|
||||
|
||||
/** Elimina e restituisce il primo elemento della coda (null se <20> vuota). */
|
||||
public E dequeue();
|
||||
|
||||
/** Restituisce il primo elemento della coda, senza toglierlo (null se <20> vuota). */
|
||||
public E first();
|
||||
|
||||
}
|
||||
44
src/it/algoritmi/adt/Stack.java
Normal file
44
src/it/algoritmi/adt/Stack.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package it.algoritmi.adt;
|
||||
|
||||
/**
|
||||
* Una raccolta di oggetti che vengono inseriti e eliminati secondo il principio
|
||||
* last-in first-out. Anche se ha uno scopo simile, questa interfaccia <20> diversa da
|
||||
* java.util.Stack
|
||||
*
|
||||
* @author fscotto
|
||||
*
|
||||
*/
|
||||
public interface Stack<E> {
|
||||
|
||||
/**
|
||||
* Restituisce il numero di elementi presenti nella pila.
|
||||
* @return il numero di elementi presenti nella pila.
|
||||
*/
|
||||
int size();
|
||||
|
||||
/**
|
||||
* Verifica se la pila <20> vuota.
|
||||
* @return true se e solo se la pila <20> vuota
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Inserisce un elemento in cima alla pila.
|
||||
* @param e l'elemento da inserire
|
||||
*/
|
||||
void push(E e);
|
||||
|
||||
|
||||
/**
|
||||
* Restituisce l'elemento in cima alla pila, senza eliminarlo.
|
||||
* @return l'elemento in cima alla pila (o null se la pila <20> vuota)
|
||||
*/
|
||||
E top();
|
||||
|
||||
/**
|
||||
* Elimina e restituisce l'elemento che si trova in cima alla pila.
|
||||
* @return l'elemento eliminato (o null se la pila <20> vuota)
|
||||
*/
|
||||
E pop();
|
||||
|
||||
}
|
||||
82
src/it/algoritmi/adt/dequeue/ArrayDeque.java
Normal file
82
src/it/algoritmi/adt/dequeue/ArrayDeque.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package it.algoritmi.adt.dequeue;
|
||||
|
||||
import it.algoritmi.adt.Deque;
|
||||
|
||||
public class ArrayDeque<E> implements Deque<E> {
|
||||
private E[] data;
|
||||
private int size;
|
||||
private int f;
|
||||
|
||||
public static final int CAPACITY = 1000;
|
||||
|
||||
public ArrayDeque() {
|
||||
this(CAPACITY);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"all"})
|
||||
public ArrayDeque(int capacity) {
|
||||
data = (E[]) new Object[capacity];
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E first() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data[f];
|
||||
}
|
||||
|
||||
@Override
|
||||
public E last() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data[size-1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E element) throws IllegalStateException {
|
||||
final int len = data.length;
|
||||
if (size() == len) {
|
||||
throw new IllegalStateException("Queue is full");
|
||||
}
|
||||
final int avail = (f - 1 + len) % len;
|
||||
data[avail] = element;
|
||||
++size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E element) throws IllegalStateException {
|
||||
final int len = data.length;
|
||||
if (size() == len) {
|
||||
throw new IllegalStateException("Queue is full");
|
||||
}
|
||||
final int avail = (f + size) % len;
|
||||
data[avail] = element;
|
||||
++size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
49
src/it/algoritmi/adt/dequeue/LinkedDeque.java
Normal file
49
src/it/algoritmi/adt/dequeue/LinkedDeque.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package it.algoritmi.adt.dequeue;
|
||||
|
||||
import it.algoritmi.adt.Deque;
|
||||
import it.algoritmi.adt.list.DoublyLinkedList;
|
||||
|
||||
public class LinkedDeque<E> implements Deque<E> {
|
||||
private DoublyLinkedList<E> l = new DoublyLinkedList<>();
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return l.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return l.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E first() {
|
||||
return l.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E last() {
|
||||
return l.last();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E element) {
|
||||
l.addFirst(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E element) {
|
||||
l.addLast(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
return l.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
return l.removeLast();
|
||||
}
|
||||
|
||||
}
|
||||
161
src/it/algoritmi/adt/list/ArrayList.java
Normal file
161
src/it/algoritmi/adt/list/ArrayList.java
Normal file
@@ -0,0 +1,161 @@
|
||||
package it.algoritmi.adt.list;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import it.algoritmi.adt.List;
|
||||
|
||||
public class ArrayList<E> implements List<E> {
|
||||
// variabili di esemplare
|
||||
public static final int CAPACITY = 16; // capacità predefinita dell'array
|
||||
|
||||
private E[] data; // array generico per memorizzare gli elementi
|
||||
private int size; // numero di elementi nella lista
|
||||
|
||||
/**
|
||||
* Costruttore di una lista standard
|
||||
*/
|
||||
public ArrayList() {
|
||||
this(CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Costruisce una lista con capacità data
|
||||
* @param capacity
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public ArrayList(int capacity) {
|
||||
data = (E[]) new Object[capacity];
|
||||
size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il numero di elementi presenti nella lista.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce true se e solo se la lista è vuota.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce l'elemento corrispondente all'indice i,
|
||||
* senza eliminarlo.
|
||||
*/
|
||||
@Override
|
||||
public E get(int i) throws IndexOutOfBoundsException {
|
||||
checkIndex(i, size);
|
||||
return data[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sostituisce con e l'elemento di indice i;
|
||||
* restituisce l'elemento sostituito.
|
||||
*/
|
||||
@Override
|
||||
public E set(int i, E e) throws IndexOutOfBoundsException {
|
||||
checkIndex(i, size);
|
||||
E tmp = data[i];
|
||||
data[i] = e;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserisce e come elemento di indice i,
|
||||
* spostando gli elementi successivi.
|
||||
*/
|
||||
@Override
|
||||
public void add(int i, E e) throws IndexOutOfBoundsException {
|
||||
checkIndex(i, size + 1);
|
||||
if(size == data.length) resize(2 * data.length);
|
||||
for(int k = size - 1; k >= i; --k) data[k + 1] = data[k];
|
||||
data[i] = e;
|
||||
++size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina e restituisce l'elemento con l'indice i,
|
||||
* spostando i successivi.
|
||||
*/
|
||||
@Override
|
||||
public E remove(int i) throws IndexOutOfBoundsException {
|
||||
checkIndex(i, size);
|
||||
E tmp = data[i];
|
||||
for(int k = i; k <= size-1; ++k) data[k] = data[k + 1];
|
||||
data[size - 1] = null;
|
||||
--size;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controlla se l'indice data appartiene all'intervallo [0, n - 1]
|
||||
* @param i
|
||||
* @param n
|
||||
* @throws IndexOutOfBoundsException
|
||||
*/
|
||||
protected void checkIndex(int i, int n) throws IndexOutOfBoundsException {
|
||||
if(i < 0 || i >= n) throw new IndexOutOfBoundsException("Illegal index: " + i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ridimensiona l'array interno in modo che abbia capacità >= size.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void resize(int capacity) {
|
||||
E[] tmp = (E[]) new Object[capacity];
|
||||
for(int k = 0; k < size; ++k) tmp[k] = data[k];
|
||||
data = tmp;
|
||||
}
|
||||
|
||||
private class ArrayIterator implements Iterator<E> {
|
||||
private int j = 0; // indice del prossimo elemento da restituire
|
||||
private boolean removable = false; // si può invocare remove ora?
|
||||
|
||||
/**
|
||||
* Verifica se l'iteratore ha ancora oggetti da restituire
|
||||
* @return true se e solo se ci sono ancora oggetti da restituire
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return j < size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce l'oggetto successivo presente nell'iteratore.
|
||||
*
|
||||
* @return l'oggetto successivo
|
||||
* @throws NoSuchElementException
|
||||
*/
|
||||
@Override
|
||||
public E next() throws NoSuchElementException {
|
||||
if(j == size()) throw new NoSuchElementException("No next element");
|
||||
removable = true; // questo elemento potrà poi essere rimosso
|
||||
return data[j++]; // post-incremente di j, così è pronto per il futuro
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina l'elemento restituito dalla più recente invocazione di next.
|
||||
* @throws IllegalStateException se next non è mai stato invocato
|
||||
* @throws IllegalStateException se remove è già stato invocato dopo next
|
||||
*/
|
||||
@Override
|
||||
public void remove() throws IllegalStateException {
|
||||
if(!removable) throw new IllegalStateException("nothing to remove");
|
||||
ArrayList.this.remove(j-1);
|
||||
--j;
|
||||
removable = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new ArrayIterator();
|
||||
}
|
||||
|
||||
}
|
||||
86
src/it/algoritmi/adt/list/CircularyLinkedList.java
Normal file
86
src/it/algoritmi/adt/list/CircularyLinkedList.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package it.algoritmi.adt.list;
|
||||
|
||||
public class CircularyLinkedList<E> {
|
||||
private Node<E> tail = null;
|
||||
private int size = 0;
|
||||
|
||||
private static class Node<E> {
|
||||
private E element;
|
||||
private Node<E> next;
|
||||
|
||||
public Node(E e, Node<E> n) {
|
||||
element = e;
|
||||
next = n;
|
||||
}
|
||||
|
||||
public E getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public Node<E> getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(Node<E> n) {
|
||||
next = n;
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
public E first() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return tail.getNext().getElement();
|
||||
}
|
||||
|
||||
public E last() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return tail.getElement();
|
||||
}
|
||||
|
||||
public void rotate() {
|
||||
if (tail != null) {
|
||||
tail = tail.getNext();
|
||||
}
|
||||
}
|
||||
|
||||
public void addFirst(E e) {
|
||||
if(size == 0) {
|
||||
tail = new Node<>(e, null);
|
||||
tail.setNext(tail);
|
||||
} else {
|
||||
Node<E> newest = new Node<>(e, tail.getNext());
|
||||
tail.setNext(newest);
|
||||
}
|
||||
size++;
|
||||
}
|
||||
|
||||
public void addLast(E e) {
|
||||
addFirst(e);
|
||||
tail = tail.getNext();
|
||||
}
|
||||
|
||||
public E removeFirst() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Node<E> head = tail.getNext();
|
||||
if(head == tail) {
|
||||
tail = null;
|
||||
} else {
|
||||
tail.setNext(head.getNext());
|
||||
}
|
||||
size--;
|
||||
return head.getElement();
|
||||
}
|
||||
}
|
||||
120
src/it/algoritmi/adt/list/DoublyLinkedList.java
Normal file
120
src/it/algoritmi/adt/list/DoublyLinkedList.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package it.algoritmi.adt.list;
|
||||
|
||||
public class DoublyLinkedList<E> {
|
||||
private Node<E> header;
|
||||
private Node<E> trailer;
|
||||
private int size = 0;
|
||||
|
||||
private static class Node<E> {
|
||||
private E element;
|
||||
private Node<E> prev;
|
||||
private Node<E> next;
|
||||
|
||||
private Node(E e, Node<E> prev, Node<E> next) {
|
||||
element = e;
|
||||
this.prev = prev;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public Node<E> getPrev() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public void setPrev(Node<E> prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
public Node<E> getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(Node<E> next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public E getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DoublyLinkedList() {
|
||||
header = new Node<>(null, null, null);
|
||||
trailer = new Node<>(null, header, null);
|
||||
header.setNext(trailer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il numero di elementi presenti nella lista
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/** Restituisce true se e solo se la lista <20> vuota */
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
/** Restituisce il primo elemento della lista, senza eliminarlo. */
|
||||
public E first() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return header.getNext().getElement();
|
||||
}
|
||||
|
||||
/** Restituisce l'ultimo elemento della lista, senza eliminarlo. */
|
||||
public E last() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return trailer.getPrev().getElement();
|
||||
}
|
||||
|
||||
/** Aggiunge un elemento all'inizio della lista. */
|
||||
public void addFirst(E e) {
|
||||
addBetween(e, header, header.getNext());
|
||||
}
|
||||
|
||||
/** Aggiunge un elemento alla fine della lista. */
|
||||
public void addLast(E e) {
|
||||
addBetween(e, trailer.getPrev(), trailer);
|
||||
}
|
||||
|
||||
/** Elimina e restituisce il primo elemento della lista. */
|
||||
public E removeFirst() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return remove(header.getNext());
|
||||
}
|
||||
|
||||
/** Elimina e restituisce l'ultimo elemento della lista. */
|
||||
public E removeLast() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return remove(trailer.getPrev());
|
||||
}
|
||||
|
||||
/** Elimina dall lista il nodo indicato e restituisce il suo elemento. */
|
||||
private E remove(Node<E> node) {
|
||||
Node<E> predecessor = node.getPrev();
|
||||
Node<E> successor = node.getNext();
|
||||
predecessor.setNext(successor);
|
||||
successor.setPrev(predecessor);
|
||||
--size;
|
||||
return node.getElement();
|
||||
}
|
||||
|
||||
/** Aggiunge l'elemento e alla lista, tra i due nodi dati. */
|
||||
private void addBetween(E e, Node<E> predecessor, Node<E> successor) {
|
||||
// crea un nuovo nodo e lo collega alla lista
|
||||
Node<E> newest = new Node<>(e, predecessor, successor);
|
||||
predecessor.setNext(newest);
|
||||
successor.setPrev(newest);
|
||||
++size;
|
||||
}
|
||||
|
||||
}
|
||||
111
src/it/algoritmi/adt/list/FavoritesList.java
Normal file
111
src/it/algoritmi/adt/list/FavoritesList.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package it.algoritmi.adt.list;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import it.algoritmi.adt.Position;
|
||||
import it.algoritmi.adt.PositionalList;
|
||||
|
||||
/** Gestisce una lista di elementi ordinati in base alla frequenza di accesso. */
|
||||
public class FavoritesList<E> {
|
||||
|
||||
protected static class Item<E> {
|
||||
private E value;
|
||||
private int count;
|
||||
|
||||
public Item(E value) {
|
||||
this.value = value;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
public E getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
++this.count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PositionalList<Item<E>> list = new LinkedPositionalList<>(); // lista di oggetti
|
||||
|
||||
/** Abbreviazione per accedere al preferito memorizzato in posizione position. */
|
||||
protected E value(Position<Item<E>> position) {
|
||||
return position.getElement().getValue();
|
||||
}
|
||||
|
||||
/** Abbreviazione per accedere al conteggio associato alla posizione position. */
|
||||
protected int count(Position<Item<E>> position) {
|
||||
return position.getElement().getCount();
|
||||
}
|
||||
|
||||
/** Restituisce la Position che ha value uguale a element (o null se non trovato). */
|
||||
protected Position<Item<E>> findPosition(E element) {
|
||||
Position<Item<E>> walk = list.first();
|
||||
while(walk != null && !element.equals(value(walk)))
|
||||
walk = list.after(walk);
|
||||
return walk;
|
||||
}
|
||||
|
||||
/** Sposta verso sinistra l'oggetto in posizione position sulla base del conteggio. */
|
||||
private void moveUp(Position<Item<E>> position) {
|
||||
int cnt = count(position); // conteggio aggiornato dell'elemento a cui si è acceduto
|
||||
Position<Item<E>> walk = position;
|
||||
while (walk != list.first() && count(list.before(walk)) < cnt)
|
||||
walk = list.before(walk); // trovato un conteggio minore a sinistra
|
||||
if(walk != position) list.addBefore(walk, list.remove(position)); // elimina e reinserisce l'oggetto
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il numero di elementi presenti
|
||||
* nella lista dei preferiti.
|
||||
*/
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce true se e solo se la lista
|
||||
* dei preferiti è vuota.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accede all'elemento element (eventualmente nuovo),
|
||||
* incrementando il suo conteggio.
|
||||
*/
|
||||
public void access(E element) {
|
||||
Position<Item<E>> position = findPosition(element); // cerca un elemento esistente
|
||||
if(position == null) position = list.addLast(new Item<E>(element)); // se nuovo, aggiunge alla fine
|
||||
position.getElement().increment(); // in ogni caso, incrementa il conteggio
|
||||
moveUp(position); // sposta a sinistra, se serve
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina dalla lista dei preferiti l'elemento
|
||||
* uguale a element (se c'è).
|
||||
*/
|
||||
public void remove(E element) {
|
||||
Position<Item<E>> position = findPosition(element); // cerca un elemento esitente
|
||||
if (position != null) list.remove(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce un contenitore iterabile con i k elementi
|
||||
* aventi più accessi.
|
||||
*/
|
||||
public Iterable<E> getFavorites(int k) throws IllegalArgumentException {
|
||||
if(k < 0 || k > size()) throw new IllegalArgumentException("Invalid k");
|
||||
PositionalList<E> result = new LinkedPositionalList<>();
|
||||
Iterator<Item<E>> iter = list.iterator();
|
||||
for(int j = 0; j < k; ++j) result.addLast(iter.next().getValue());
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
46
src/it/algoritmi/adt/list/FavoritesListMTF.java
Normal file
46
src/it/algoritmi/adt/list/FavoritesListMTF.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package it.algoritmi.adt.list;
|
||||
|
||||
import it.algoritmi.adt.Position;
|
||||
import it.algoritmi.adt.PositionalList;
|
||||
|
||||
/** Gestisce una lista di preferiti usando l'euristica move-to-front */
|
||||
public class FavoritesListMTF<E> extends FavoritesList<E> {
|
||||
|
||||
/**
|
||||
* Sposta all'inizio della lista l'oggetto in posizione position
|
||||
* a cui si è acceduto.
|
||||
*/
|
||||
protected void moveUp(Position<Item<E>> position) {
|
||||
if(position != list.first()) list.addFirst(list.remove(position)); // elimina e reinserisce all'inizio
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce un contenitore iterabile con i k elementi
|
||||
* aventi più accessi.
|
||||
*/
|
||||
@Override
|
||||
public Iterable<E> getFavorites(int k) throws IllegalArgumentException {
|
||||
if(k < 0 || k > size()) throw new IllegalArgumentException();
|
||||
|
||||
// iniziamo facendo una copia della lista originale
|
||||
PositionalList<Item<E>> tmp = new LinkedPositionalList<>();
|
||||
for(Item<E> item : list) tmp.addLast(item);
|
||||
|
||||
// cerchiamo ed eliminiamo ripetutamente l'elemento con il conteggio massimo
|
||||
PositionalList<E> result = new LinkedPositionalList<>();
|
||||
for(int j = 0; j < k; ++j) {
|
||||
Position<Item<E>> highPos = tmp.first();
|
||||
Position<Item<E>> walk = tmp.after(highPos);
|
||||
while(walk != null) {
|
||||
if(count(walk) > count(highPos))
|
||||
highPos = walk;
|
||||
walk = tmp.after(walk);
|
||||
}
|
||||
// abbiamo trovato l'elemento con il conteggio massimo
|
||||
result.addLast(value(highPos));
|
||||
tmp.remove(highPos);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
303
src/it/algoritmi/adt/list/LinkedPositionalList.java
Normal file
303
src/it/algoritmi/adt/list/LinkedPositionalList.java
Normal file
@@ -0,0 +1,303 @@
|
||||
package it.algoritmi.adt.list;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import it.algoritmi.adt.Position;
|
||||
import it.algoritmi.adt.PositionalList;
|
||||
|
||||
/** Implementazione di lista posizionale mediante lista doppiamente concatenata. */
|
||||
public class LinkedPositionalList<E> implements PositionalList<E> {
|
||||
|
||||
private static class Node<E> implements Position<E> {
|
||||
private E element; // riferimento all'elemento memorizzato in questo nodo
|
||||
private Node<E> prev; // riferimento al nodo precedente nella lista
|
||||
private Node<E> next; // riferimento al nodo seguente nella lista
|
||||
|
||||
public Node(E element, Node<E> prev, Node<E> next) {
|
||||
this.element = element;
|
||||
this.prev = prev;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public Node<E> getPrev() {
|
||||
return prev;
|
||||
}
|
||||
|
||||
public void setPrev(Node<E> prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
|
||||
public Node<E> getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(Node<E> next) {
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public void setElement(E element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getElement() throws IllegalStateException {
|
||||
if(next == null) throw new IllegalStateException("Position no longer valid");
|
||||
return element;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Node<E> header; // sentinella iniziale
|
||||
private Node<E> trailer; // sentinella finale
|
||||
private int size; // numero di elementi presenti nella lista
|
||||
|
||||
public LinkedPositionalList() {
|
||||
header = new Node<>(null, null, null); // crea la sentinella iniziale
|
||||
trailer = new Node<>(null, header, null); // trailer è preceduto da header
|
||||
header.setNext(trailer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica se la posizione è valida e la restituisce
|
||||
* sotto forma di nodo.
|
||||
*
|
||||
* @param position
|
||||
* @return
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
private Node<E> validate(Position<E> position) throws IllegalArgumentException {
|
||||
if(!(position instanceof Node)) throw new IllegalArgumentException("Invalid p");
|
||||
Node<E> node = (Node<E>) position; // cast sicuro
|
||||
if(node.getNext() == null) throw new IllegalArgumentException("p is no longer in the list");
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il nodo sotto forma di Position (o null, se è una sentinella).
|
||||
* @param node
|
||||
* @return
|
||||
*/
|
||||
private Position<E> position(Node<E> node) {
|
||||
return (node != header && node != trailer) ? node : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce il numero di elementi presenti
|
||||
* nella lista concatenata.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce true se e solo se la lista concatenata è vuota.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce la prima Position della lista (o null, se la lista è vuota).
|
||||
*/
|
||||
@Override
|
||||
public Position<E> first() {
|
||||
return position(header.getNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce l'ultima Position della lista(o null, se la lista è vuota).
|
||||
*/
|
||||
@Override
|
||||
public Position<E> last() {
|
||||
return position(trailer.getPrev());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce la Position che precede p (o null, se p è la prima).
|
||||
*/
|
||||
@Override
|
||||
public Position<E> before(Position<E> position) throws IllegalArgumentException {
|
||||
Node<E> node = validate(position);
|
||||
return position(node.getPrev());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce la Posizione che segue p (o null, se p è l'ultima).
|
||||
*/
|
||||
@Override
|
||||
public Position<E> after(Position<E> position) throws IllegalArgumentException {
|
||||
Node<E> node = validate(position);
|
||||
return position(node.getNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggiunge l'elemento e alla lista concatenata
|
||||
* tra i due nodi dati.
|
||||
*
|
||||
* @param element
|
||||
* @param pred
|
||||
* @param succ
|
||||
* @return
|
||||
*/
|
||||
private Position<E> addBeetween(E element, Node<E> pred, Node<E> succ) {
|
||||
Node<E> newest = new Node<>(element, pred, succ);
|
||||
pred.setNext(newest);
|
||||
succ.setPrev(newest);
|
||||
++size;
|
||||
return newest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserisce l'elemento e all'inizio della lista;
|
||||
* ne restituisce la posizione.
|
||||
*/
|
||||
@Override
|
||||
public Position<E> addFirst(E element) {
|
||||
return addBeetween(element, header, header.getNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserisce l'elemento e alla fine della lista;
|
||||
* ne restituisce la posizione.
|
||||
*/
|
||||
@Override
|
||||
public Position<E> addLast(E element) {
|
||||
return addBeetween(element, trailer.getPrev(), trailer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserisce l'elemento e prima della Position p;
|
||||
* ne restituisce la posizione.
|
||||
*/
|
||||
@Override
|
||||
public Position<E> addBefore(Position<E> position, E element) throws IllegalArgumentException {
|
||||
Node<E> node = validate(position);
|
||||
return addBeetween(element, node.getPrev(), node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserisce l'elemento e dopo la Position p;
|
||||
* ne restituisce la posizione.
|
||||
*/
|
||||
@Override
|
||||
public Position<E> addAfter(Position<E> position, E element) throws IllegalArgumentException {
|
||||
Node<E> node = validate(position);
|
||||
return addBeetween(element, node, node.getNext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sostituisce l'elemento nella Position p;
|
||||
* restituisce l'elemento sostituito.
|
||||
*/
|
||||
@Override
|
||||
public E set(Position<E> position, E element) throws IllegalArgumentException {
|
||||
Node<E> node = validate(position);
|
||||
E answer = node.getElement();
|
||||
node.setElement(element);
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina e restituisce l'elemento nella Position p (poi p non è più valida).
|
||||
*/
|
||||
@Override
|
||||
public E remove(Position<E> position) throws IllegalArgumentException {
|
||||
Node<E> node = validate(position);
|
||||
Node<E> predecessor = node.getPrev();
|
||||
Node<E> successor = node.getNext();
|
||||
predecessor.setNext(successor);
|
||||
successor.setPrev(predecessor);
|
||||
--size;
|
||||
E answer = node.getElement();
|
||||
node.setElement(null);
|
||||
node.setNext(null);
|
||||
node.setPrev(null);
|
||||
return answer;
|
||||
}
|
||||
|
||||
private class PositionIterator implements Iterator<Position<E>> {
|
||||
private Position<E> cursor = first(); // prossima posizione da restituire
|
||||
private Position<E> recent = null; // posizione restituita più recente
|
||||
|
||||
/**
|
||||
* Verifica se l'iteratore ha altro da restituire.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return cursor != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce la prossima posizione dell'iteratore.
|
||||
*/
|
||||
@Override
|
||||
public Position<E> next() throws NoSuchElementException {
|
||||
if(cursor == null) throw new NoSuchElementException("nothing left");
|
||||
recent = cursor;
|
||||
cursor = after(cursor);
|
||||
return recent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina l'elemento restituito dalla più recente invocazione di next.
|
||||
*/
|
||||
@Override
|
||||
public void remove() throws IllegalStateException {
|
||||
if(recent == null) throw new IllegalArgumentException("nothing to remove");
|
||||
LinkedPositionalList.this.remove(recent); // rimuova l'elemento della lista
|
||||
recent = null; // non si può invocare di nuovo remove prima di next
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class PositionIterable implements Iterable<Position<E>> {
|
||||
|
||||
@Override
|
||||
public Iterator<Position<E>> iterator() {
|
||||
return new PositionIterator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce una rappresentazione iterabile delle posizioni dela lista.
|
||||
*/
|
||||
@Override
|
||||
public Iterable<Position<E>> positions() {
|
||||
return new PositionIterable(); // crea un nuovo esemplare della classe interna
|
||||
}
|
||||
|
||||
/**
|
||||
* Adatta l'iteratore restituito da positions() perchè restituisca elementi.
|
||||
*/
|
||||
private class ElementIterator implements Iterator<E> {
|
||||
Iterator<Position<E>> it = new PositionIterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
return it.next().getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restituisce un iteratore degli elementi memorizzati nella lista.
|
||||
*/
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new ElementIterator();
|
||||
}
|
||||
|
||||
}
|
||||
123
src/it/algoritmi/adt/list/SinglyLinkedList.java
Normal file
123
src/it/algoritmi/adt/list/SinglyLinkedList.java
Normal file
@@ -0,0 +1,123 @@
|
||||
package it.algoritmi.adt.list;
|
||||
|
||||
public class SinglyLinkedList<E> implements Cloneable {
|
||||
private Node<E> head = null;
|
||||
private Node<E> tail = null;
|
||||
private int size = 0;
|
||||
|
||||
private static class Node<E> {
|
||||
private E element;
|
||||
private Node<E> next;
|
||||
|
||||
public Node(E e, Node<E> n) {
|
||||
element = e;
|
||||
next = n;
|
||||
}
|
||||
|
||||
public E getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public Node<E> getNext() {
|
||||
return next;
|
||||
}
|
||||
|
||||
public void setNext(Node<E> n) {
|
||||
next = n;
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
public E first() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return head.getElement();
|
||||
}
|
||||
|
||||
public E last() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return tail.getElement();
|
||||
}
|
||||
|
||||
public void addFirst(E e) {
|
||||
head = new Node<>(e, head);
|
||||
if(size == 0) {
|
||||
tail = head;
|
||||
}
|
||||
size++;
|
||||
}
|
||||
|
||||
public void addLast(E e) {
|
||||
Node<E> newest = new Node<>(e, null);
|
||||
if(isEmpty()) {
|
||||
head = newest;
|
||||
} else {
|
||||
tail.setNext(newest);
|
||||
}
|
||||
tail = newest;
|
||||
size++;
|
||||
}
|
||||
|
||||
public E removeFirst() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
E answer = head.getElement();
|
||||
head = head.getNext();
|
||||
size--;
|
||||
if (size == 0) {
|
||||
tail = null;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SinglyLinkedList other = (SinglyLinkedList) obj;
|
||||
if (size != other.size)
|
||||
return false;
|
||||
Node walkA = head;
|
||||
Node walkB = other.head;
|
||||
while(walkA != null) {
|
||||
if (!walkA.getElement().equals(walkB.getElement()))
|
||||
return false;
|
||||
walkA = walkA.getNext();
|
||||
walkB = walkB.getNext();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public SinglyLinkedList<E> clone() throws CloneNotSupportedException {
|
||||
SinglyLinkedList<E> other = (SinglyLinkedList<E>) super.clone();
|
||||
if (size > 0) {
|
||||
other.head = new Node<>(head.getElement(), null);
|
||||
Node<E> walk = head.getNext();
|
||||
Node<E> otherTail = other.head;
|
||||
while(walk != null) {
|
||||
Node<E> newest = new Node<>(walk.getElement(), null);
|
||||
otherTail.setNext(newest);
|
||||
otherTail = newest;
|
||||
walk = walk.getNext();
|
||||
}
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
}
|
||||
62
src/it/algoritmi/adt/queue/ArrayQueue.java
Normal file
62
src/it/algoritmi/adt/queue/ArrayQueue.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package it.algoritmi.adt.queue;
|
||||
|
||||
import it.algoritmi.adt.Queue;
|
||||
|
||||
public class ArrayQueue<E> implements Queue<E> {
|
||||
public static final int CAPACITY = 1000;
|
||||
|
||||
private E[] data;
|
||||
private int size;
|
||||
private int f;
|
||||
|
||||
public ArrayQueue() {
|
||||
this(CAPACITY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ArrayQueue(int capacity) {
|
||||
data = (E[]) new Object[capacity];
|
||||
size = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(E element) throws IllegalStateException {
|
||||
if (size() == data.length) {
|
||||
throw new IllegalStateException("Queue is full");
|
||||
}
|
||||
int avail = (f + size) % data.length;
|
||||
data[avail] = element;
|
||||
++size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E dequeue() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
E answer = data[f];
|
||||
data[f] = null;
|
||||
f = (f + 1) % data.length;
|
||||
--size;
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E first() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data[f];
|
||||
}
|
||||
|
||||
}
|
||||
35
src/it/algoritmi/adt/queue/DoubleLinkedQueue.java
Normal file
35
src/it/algoritmi/adt/queue/DoubleLinkedQueue.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package it.algoritmi.adt.queue;
|
||||
|
||||
import it.algoritmi.adt.Deque;
|
||||
import it.algoritmi.adt.Queue;
|
||||
import it.algoritmi.adt.dequeue.LinkedDeque;
|
||||
|
||||
public class DoubleLinkedQueue<E> implements Queue<E> {
|
||||
private Deque<E> d = new LinkedDeque<>();
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return d.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return d.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(E element) {
|
||||
d.addFirst(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E dequeue() {
|
||||
return d.removeLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E first() {
|
||||
return d.first();
|
||||
}
|
||||
|
||||
}
|
||||
14
src/it/algoritmi/adt/queue/LinkedCircularQueue.java
Normal file
14
src/it/algoritmi/adt/queue/LinkedCircularQueue.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package it.algoritmi.adt.queue;
|
||||
|
||||
import it.algoritmi.adt.CircularQueue;
|
||||
import it.algoritmi.adt.list.CircularyLinkedList;
|
||||
|
||||
public class LinkedCircularQueue<E> extends LinkedQueue<E> implements CircularQueue<E> {
|
||||
private CircularyLinkedList<E> list = new CircularyLinkedList<>();
|
||||
|
||||
@Override
|
||||
public void rotate() {
|
||||
list.rotate();
|
||||
}
|
||||
|
||||
}
|
||||
34
src/it/algoritmi/adt/queue/LinkedQueue.java
Normal file
34
src/it/algoritmi/adt/queue/LinkedQueue.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package it.algoritmi.adt.queue;
|
||||
|
||||
import it.algoritmi.adt.Queue;
|
||||
import it.algoritmi.adt.list.SinglyLinkedList;
|
||||
|
||||
public class LinkedQueue<E> implements Queue<E> {
|
||||
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(E element) {
|
||||
list.addLast(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E dequeue() {
|
||||
return list.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E first() {
|
||||
return list.first();
|
||||
}
|
||||
|
||||
}
|
||||
56
src/it/algoritmi/adt/stack/ArrayStack.java
Normal file
56
src/it/algoritmi/adt/stack/ArrayStack.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package it.algoritmi.adt.stack;
|
||||
|
||||
import it.algoritmi.adt.Stack;
|
||||
|
||||
public class ArrayStack<E> implements Stack<E> {
|
||||
public static final int CAPACITY = 1000;
|
||||
private E[] data;
|
||||
private int t = -1;
|
||||
|
||||
public ArrayStack() {
|
||||
this(CAPACITY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ArrayStack(int capacity) {
|
||||
data = (E[]) new Object[capacity];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return t + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return t == -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(E element) throws IllegalStateException {
|
||||
if (size() == data.length) {
|
||||
throw new IllegalStateException("Stack is full");
|
||||
}
|
||||
data[++t] = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E top() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return data[t];
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pop() {
|
||||
if(isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
E answer = data[t];
|
||||
data[t] = null;
|
||||
t--;
|
||||
return answer;
|
||||
}
|
||||
|
||||
}
|
||||
35
src/it/algoritmi/adt/stack/DoubledLinkedStack.java
Normal file
35
src/it/algoritmi/adt/stack/DoubledLinkedStack.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package it.algoritmi.adt.stack;
|
||||
|
||||
import it.algoritmi.adt.Deque;
|
||||
import it.algoritmi.adt.Stack;
|
||||
import it.algoritmi.adt.dequeue.LinkedDeque;
|
||||
|
||||
public class DoubledLinkedStack<E> implements Stack<E> {
|
||||
private Deque<E> d = new LinkedDeque<>();
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return d.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return d.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(E element) {
|
||||
d.addFirst(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E top() {
|
||||
return d.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pop() {
|
||||
return d.removeFirst();
|
||||
}
|
||||
|
||||
}
|
||||
34
src/it/algoritmi/adt/stack/LinkedStack.java
Normal file
34
src/it/algoritmi/adt/stack/LinkedStack.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package it.algoritmi.adt.stack;
|
||||
|
||||
import it.algoritmi.adt.Stack;
|
||||
import it.algoritmi.adt.list.SinglyLinkedList;
|
||||
|
||||
public class LinkedStack<E> implements Stack<E> {
|
||||
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return list.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(E element) {
|
||||
list.addFirst(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E top() {
|
||||
return list.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pop() {
|
||||
return list.removeFirst();
|
||||
}
|
||||
|
||||
}
|
||||
56
src/it/algoritmi/test/ADTs.java
Normal file
56
src/it/algoritmi/test/ADTs.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
import it.algoritmi.adt.Deque;
|
||||
import it.algoritmi.adt.Queue;
|
||||
import it.algoritmi.adt.Stack;
|
||||
import it.algoritmi.adt.dequeue.ArrayDeque;
|
||||
import it.algoritmi.adt.queue.LinkedQueue;
|
||||
import it.algoritmi.adt.stack.ArrayStack;
|
||||
|
||||
public class ADTs {
|
||||
|
||||
public static <E> void transfer(Stack<E> s, Stack<E> t) {
|
||||
if(!s.isEmpty()) {
|
||||
for(int i = 0, len = s.size(); i < len; ++i)
|
||||
t.push(s.pop());
|
||||
}
|
||||
}
|
||||
|
||||
public static <E> void removeAll(Stack<E> s) {
|
||||
if(s.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
s.pop();
|
||||
removeAll(s);
|
||||
}
|
||||
|
||||
public static <E> void shuffle(Deque<E> d) {
|
||||
Queue<E> q = new LinkedQueue<>();
|
||||
// TODO
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <E> Stack<E> buildStack(E... elements) {
|
||||
Stack<E> result = new ArrayStack<>();
|
||||
for(E elem : elements)
|
||||
result.push(elem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <E> Deque<E> buildDequeue(E... elements) {
|
||||
Deque<E> result = new ArrayDeque<>();
|
||||
for(E elem : elements)
|
||||
result.addLast(elem);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Stack<Integer> s1 = buildStack(1, 2, 3, 4, 5);
|
||||
Stack<Integer> s2 = buildStack(6, 7, 8, 9, 0);
|
||||
transfer(s1, s2);
|
||||
removeAll(s2);
|
||||
Deque<Integer> dk = buildDequeue(1, 2, 3, 4, 5, 6, 7, 8);
|
||||
}
|
||||
|
||||
}
|
||||
31
src/it/algoritmi/test/ArithmeticMatcher.java
Normal file
31
src/it/algoritmi/test/ArithmeticMatcher.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
import it.algoritmi.adt.Stack;
|
||||
import it.algoritmi.adt.stack.LinkedStack;
|
||||
|
||||
public class ArithmeticMatcher {
|
||||
|
||||
public static boolean isMatched(String expression) {
|
||||
final String opening = "({[";
|
||||
final String closing = ")}]";
|
||||
Stack<Character> buffer = new LinkedStack<>();
|
||||
for(char c : expression.toCharArray()) {
|
||||
if(opening.indexOf(c) != -1) {
|
||||
buffer.push(c);
|
||||
} else if(closing.indexOf(c) != -1) {
|
||||
if(buffer.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if(closing.indexOf(c) != opening.indexOf(buffer.pop())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer.isEmpty();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String exp = "(10 + 4) * 89";
|
||||
System.out.println(isMatched(exp));
|
||||
}
|
||||
}
|
||||
47
src/it/algoritmi/test/CaesarCipher.java
Normal file
47
src/it/algoritmi/test/CaesarCipher.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
public class CaesarCipher {
|
||||
protected char[] encoder = new char[26];
|
||||
protected char[] decoder = new char[26];
|
||||
|
||||
public CaesarCipher(int rotation) {
|
||||
for (int k = 0; k < 26; ++k) {
|
||||
encoder[k] = (char) ('A' + (k + rotation) % 26);
|
||||
decoder[k] = (char) ('A' + (k - rotation + 26) % 26);
|
||||
}
|
||||
}
|
||||
|
||||
/** Restituisce il messaggio cifrato. */
|
||||
public String encrypt(String message) {
|
||||
return trasform(message, encoder);
|
||||
}
|
||||
|
||||
/** Restituisce il messaggio decifrato. */
|
||||
public String decrypt(String secret) {
|
||||
return trasform(secret, decoder);
|
||||
}
|
||||
|
||||
/** Restituisce la trasformazione della stringa ricevuta secondo il codice dato. */
|
||||
private String trasform(String original, char[] code) {
|
||||
char[] msg = original.toCharArray();
|
||||
for (int k = 0; k < msg.length; ++k) {
|
||||
if(Character.isUpperCase(msg[k])) {
|
||||
int j = msg[k] - 'A';
|
||||
msg[k] = code[j];
|
||||
}
|
||||
}
|
||||
return new String(msg);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CaesarCipher cipher = new CaesarCipher(3);
|
||||
System.out.println("Encryption code = " + new String(cipher.encoder));
|
||||
System.out.println("Decryption code = " + new String(cipher.decoder));
|
||||
String message = "THE EAGLE IS IN PLAY; MEET AT JOE'S.";
|
||||
String coded = cipher.encrypt(message);
|
||||
System.out.println("Secret: " + coded);
|
||||
String answer = cipher.decrypt(coded);
|
||||
System.out.println("Message: " + answer);
|
||||
}
|
||||
|
||||
}
|
||||
83
src/it/algoritmi/test/CreditCard.java
Normal file
83
src/it/algoritmi/test/CreditCard.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
public class CreditCard {
|
||||
private String customer;
|
||||
private String bank;
|
||||
private String account;
|
||||
private int limit;
|
||||
protected double balance;
|
||||
|
||||
public CreditCard(String customer, String bank, String account, int limit) {
|
||||
this(customer, bank, account, limit, 0.0);
|
||||
}
|
||||
|
||||
public CreditCard(String customer, String bank, String account, int limit, double balance) {
|
||||
this.customer = customer;
|
||||
this.bank = bank;
|
||||
this.account = account;
|
||||
this.limit = limit;
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public String getCustomer() {
|
||||
return customer;
|
||||
}
|
||||
|
||||
public void setCustomer(String customer) {
|
||||
this.customer = customer;
|
||||
}
|
||||
|
||||
public String getBank() {
|
||||
return bank;
|
||||
}
|
||||
|
||||
public void setBank(String bank) {
|
||||
this.bank = bank;
|
||||
}
|
||||
|
||||
public String getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public void setAccount(String account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public double getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(double balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public boolean charge(double price) {
|
||||
if(price + balance > limit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
balance += price;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void makePayment(double amount) {
|
||||
balance -= amount;
|
||||
}
|
||||
|
||||
public static void printSummary(CreditCard card) {
|
||||
System.out.println("Customer = " + card.customer);
|
||||
System.out.println("Bank = " + card.bank);
|
||||
System.out.println("Account = " + card.account);
|
||||
System.out.println("Balance = " + card.balance);
|
||||
System.out.println("Limit = " + card.limit);
|
||||
}
|
||||
|
||||
}
|
||||
36
src/it/algoritmi/test/HTMLMatcher.java
Normal file
36
src/it/algoritmi/test/HTMLMatcher.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
import it.algoritmi.adt.Stack;
|
||||
import it.algoritmi.adt.stack.LinkedStack;
|
||||
|
||||
public class HTMLMatcher {
|
||||
|
||||
public static boolean isHTMLMatched(String html) {
|
||||
Stack<String> buffer = new LinkedStack<>();
|
||||
int j = html.indexOf('<');
|
||||
while(j != -1) {
|
||||
int k = html.indexOf('>', j+1);
|
||||
if(k == -1) {
|
||||
return false;
|
||||
}
|
||||
String tag = html.substring(j+1, k);
|
||||
if(!tag.startsWith("/")) {
|
||||
buffer.push(tag);
|
||||
} else {
|
||||
if(buffer.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if(!tag.substring(1).equals(buffer.pop())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
j = html.indexOf('<', k+1);
|
||||
}
|
||||
return buffer.isEmpty();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
40
src/it/algoritmi/test/Josephus.java
Normal file
40
src/it/algoritmi/test/Josephus.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
import it.algoritmi.adt.CircularQueue;
|
||||
import it.algoritmi.adt.queue.LinkedCircularQueue;
|
||||
|
||||
public class Josephus {
|
||||
/** Determina il vincitore del problema di Josephus usando una coda circolare. */
|
||||
public static <E> E josephus(CircularQueue<E> queue, int k) {
|
||||
if(queue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
while(queue.size() > 1) {
|
||||
for (int i = 0; i < k-1; ++i) {
|
||||
queue.rotate();
|
||||
}
|
||||
E e = queue.dequeue();
|
||||
System.out.println(" " + e + " is out");
|
||||
}
|
||||
return queue.dequeue();
|
||||
}
|
||||
|
||||
/** Costruisce una coda circolare a partire da un array di oggetti. */
|
||||
public static <E> CircularQueue<E> buildQueue(E a[]) {
|
||||
CircularQueue<E> queue = new LinkedCircularQueue<>();
|
||||
for(int i = 0; i < a.length; ++i) {
|
||||
queue.enqueue(a[i]);
|
||||
}
|
||||
return queue;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String[] a1 = {"Alice", "Bob", "Cindy", "Doug", "Ed", "Fred"};
|
||||
String[] a2 = {"Gene", "Hope", "Irene", "Jack", "Kim", "Lance"};
|
||||
String[] a3 = {"Mike", "Roberto"};
|
||||
System.out.println("First winner is " + josephus(buildQueue(a1), 3));
|
||||
System.out.println("Second winner is " + josephus(buildQueue(a2), 10));
|
||||
System.out.println("Third winner is " + josephus(buildQueue(a3), 7));
|
||||
}
|
||||
|
||||
}
|
||||
28
src/it/algoritmi/test/PredatoryCreditCard.java
Normal file
28
src/it/algoritmi/test/PredatoryCreditCard.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package it.algoritmi.test;
|
||||
|
||||
public class PredatoryCreditCard extends CreditCard {
|
||||
private double rate;
|
||||
|
||||
public PredatoryCreditCard(String customer, String bank, String account,
|
||||
int limit, double initialBalance, double rate) {
|
||||
super(customer, bank, account, limit, initialBalance);
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public void processMoth() {
|
||||
if(balance > 0) {
|
||||
double monthlyFactor = Math.pow(1 + rate, 1. / 12);
|
||||
balance *= monthlyFactor;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charge(double price) {
|
||||
boolean isSuccess = super.charge(price);
|
||||
if(!isSuccess) {
|
||||
balance += 5;
|
||||
}
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user