Laboratorio VIII: 27-Nov-2006
versione del 24-Nov-2006

Parte I
Linguaggio Java: tipi di dati astratti e strutture dati.
Strutture dati realizzate con array riempiti parzialmente e liste concatenate.

Una soluzione possibile
Realizzare un vettore
L'interfaccia MyList.java (che estende l'interfaccia Container) definisce un tipo di dati astratto in cui i dati  sono disposti in sequenza. A ciascun dato e' associata una posizione nella sequenza, espressa con un numero intero >= 0, detto indice.

Si codifichino le classi ArrayVector.java e LinkedListVector.java per realizzare l'interfaccia MyList,  usando un array riempito parzialmente nella prima, una lista concatenata nella seconda.

Si provino le classi realizzate con le seguenti classi di prova fornite dal docente: ArrayVectorTester.java e LinkedListVectorTester.java.

Si risponda, successivamente, alle seguenti domande:

1. Qual e' la complessita' temporale del metodo public void add(int index, Object obj)  nelle due realizzazioni?
2. Qual e' la complessita' temporale del metodo public Object get(int index)   nelle due realizzazioni?
3. Qual e' la complessita' temporale del metodo public int indexOf(Object obj)   nelle due realizzazioni?
4. Perche' la lista concatenata risulta meno efficiente dell'array riempito parzialmente per la realizzazione di questo tipo di dati astratto?

Programmazione di LinkedListVector.java

Ci sono due alternative:

a. Programmare la classe lista concatenata, realizzata come a lezione, e usare nella classe LinkedListVector un esemplare di questa classe (LinkedList) per memorizzare i dati. Nella classe LinkedList codificata a lezione non si e' definito il metodo int size() e quindi si realizzi il conteggio degli elementi del contenitore nella classe LinkedListVector (ad esempio definendo e aggiornando una variabile int size, come sa fa solitamente).

b. Definire la classe nodo (ListNode a lezione) come classe interna della classe LinkedListVector e gestire internamente ai metodi della classe LinkedListVector la programmazione della lista concatenata.
La classe ListNode, nella forma piu' semplice, definisce variabili di esemplare senza specificatoredi accesso, rendendole visibili nella classe in cui ListNode e' contenuta. Non e' una violazione del principio dell'incapsulamento, perche', essendo ListNode una classe interna, non e' visibile al di fuori della classe in cui e' definita:

   // Nodo della lista concatenata: classe interna
   class ListNode
   {
      Object element;
// visibile nella classe di cui ListNode e' classe interna
      ListNode next;
  // visibile nella classe di cui ListNode e' classe interna

      public ListNode(Object obj, ListNode n)
      {
         element = obj;
         next = n;
      }
     
      public ListNode()
      {
         this(null, null);
      }
   }


Con la definizione riportata sopra della classe ListNode, il metodo public void add(Object obj) della classe LinkedListVector puo' essere codificato come segue, dove la variabile int size conta gli elementi contenuti nel vettore:

  /**
      aggiunge
alla fine di questo Vettore l'elemento specificato
      O(1)
      @param obj nuovo elemento da aggiungere
   */
   public void add(Object dato)
   {
      tail.next = new ListNode(dato, null);
      tail = tail.next;
      size++;
   }


public void add(Object obj)
 
Rappresentazione grafica dell'inserimento di un dato nella lista concatenata
ArrayVector.java
LinkedListVector.java
Realizzare una lista doppiamente concatenata
Si realizzi una lista doppiamente concatenata nella classe DoublyLinkedList.java.
Usare due nodi sentinella, senza dati, per marcare il primo node (head) e l'ultimo (tail).
La lista vuota sia costituita dai due nodi sentinella, come la seguente:

empty doubly linked list

Provare i metodi della classe con la classe di prova DoublyLinkedListTester.java fornita dal docente.
DoublyLinkedList.java

Parte II
Linguaggio Java: tipi di dati astratti e strutture dati. Pile e Code. Leggere e scrivere file di testo.
Una soluzione possibile
Realizzare Pile e Code
1. Scrivere il codice delle classi ArStack e ArQueue che realizzano, rispettivamente, l'interfaccia  Stack e l'interfaccia Queue (entrambe estendono l'interfaccia Container) e che usano per la memorizzazione di oggetti array riempiti parzialmente. I metodi delle classi abbiano andamento asintottico  O(1) (medio se si ridimensiona l'array).

2. Scrivere una classe Main che
- legga un testo da file, separi le righe in parole e memorizzi le parole in una pila e in una coda. Il nome del file sia passato come argomento nella riga di comando. Si consideri una parola come una stringa delimitata da spazi o caratteri di nuova riga.
- stampi il contenuto della coda in un file, una parola per riga. Il nome del file sia passato come argomento sulla riga di comando.
- stampi il contenuto della pila in un altro file. Il nome del file sia passato come argomento sulla riga di comando.

uso: $java Main inputFile outputFile1 outputFile2

3. Eseguire l'analisi del testo contenuto nel file di testo itinerario.txt.
EmptyStackException.java
EmptyQueueException.java
ArStack.java
ArQueue.java
Main.java


Coda realizzate tramite pile
Scrivere la classe QueueByStacks che realizza l'interfaccia Queue. La classe QueueByStacks usi al suo interno esclusivamente strutture dati di tipo pila (nella classe non si possono usare né array, né liste concatenate, né altre strutture dati).
Provare la classe QueueByStacks con il file di testo itinerario.txt. Per fare questo si modifichi la classe Main dell'esercizio precedente.

Suggerimento (da leggere se non riuscite a trovare una soluzione da soli).

Qual e' l'andamento asintottico della complessita' temporale dei metodi della classe QueueByStacks?

uso: $java QueueByStacksMain inputFile outputFile1 outputFile2
QueueByStacks.java
QueueByStacksMain.java
Pila realizzate tramite coda Scrivere la classe StackByQueue che realizza l'interfaccia Stack. La classe usi esclusivamente strutture dati di tipo coda (nella classe non si possono usare né array, né liste concatenate, né altre strutture dati).

Provare la classe StackByQueue con il file di testo itinerario.txt, modificando  la classe Main dell'esercizio precedente.

Suggerimento (da leggere se non riuscite a trovare una soluzione da soli).

Qual e' l'andamento asintottico della complessita' temporale dei metodi della classe StackByQueue?

uso: $java StackByQueueMain inputFile outputFile1 outputFile2
StackByQueue.java
StackByQueueMain.java
Coda realizzata tramite pila, con l'aiuto del Java Stack
Scrivere la classe RecursiveQueueBySingleStack che realizza l'interfaccia Queue. La classe usi come struttura dati una sola pila (nella classe non si possono usare né array, né liste concatenate, né altre strutture dati, né altre pile neanche temporanee).

Provare la classe RecursiveQueueBySingleStack con il file di testo itinerario.txt, modificando  la classe Main dell'esercizio precedente.

Algoritmo ricorsivo (da leggere se non riuscite a trovare una soluzione da soli).

Qual e' l'andamento asintottico della complessita' temporale dei metodi della classe RecursiveQueueBySingleStack?

uso: $java RecursiveQueueBySingleStackMain inputFile outputFile1 outputFile2
RecursiveQueueBySingleStack.java
RecursiveQueueBySingleStackMain.java