Ενότητα 2: Στοίβες Ουρές - Λίστες Ασκήσεις και Λύσεις

Σχετικά έγγραφα
ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ

Ενότητα 2: Στοίβες Ουρές - Λίστες Ασκήσεις και Λύσεις

Διάλεξη 11: Φροντιστήριο για Στοίβες. Διδάσκων: Παναγιώτης Ανδρέου. ΕΠΛ035 Δομές Δεδομένων και Αλγόριθμοι για Ηλ. Μηχ. Και Μηχ. Υπολ.

Διδάσκων: Παναγιώτης Ανδρέου

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Βασικές Δομές Δεδομένων

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Βασικές οµές εδοµένων

Στοίβες με Δυναμική Δέσμευση Μνήμης

Διάλεξη 12: Λίστες Υλοποίηση & Εφαρμογές. Διδάσκων: Παναγιώτης Ανδρέου

Υλοποίηση Λιστών. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα:

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΕΠΛ 035: οµές εδοµένων και Αλγόριθµοι για Ηλεκτρολόγους Μηχανικούς και Μηχανικούς Υπολογιστών

Ενότητα 2 Στοίβες Ουρές - Λίστες. ΗΥ240 - Παναγιώτα Φατούρου 1

Στοίβες Ουρές - Λίστες

Κατ οίκον Εργασία 2 Σκελετοί Λύσεων

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. ΕΠΛ 035: οµές εδοµένων και Αλγόριθµοι για Ηλεκτρολόγους Μηχανικούς και Μηχανικούς Υπολογιστών

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ. Δομές δεδομένων. Ενότητα 2η: Στοίβες Ουρές - Λίστες Παναγιώτα Φατούρου Τμήμα Επιστήμης Υπολογιστών

Φροντιστήριο 4 Σκελετοί Λύσεων

Εργαστήριο 4: Υλοποίηση Αφηρημένου Τύπου Δεδομένων: Ταξινομημένη Λίστα

Υλοποίηση Λειτουργιών Στοίβας Απλά(1/2)

IsEmptyList(L): επιστρέφει true αν L = < >, false

Φροντιστήριο 4 Σκελετοί Λύσεων

ΕΠΛ 231 Δομές Δεδομένων και Αλγόριθμοι 4-1

Διάλεξη 21η: Απλά Συνδεδεμένες Λίστες

Αναδροµή. Σε αυτήν την (βοηθητική) ενότητα θα µελετηθούν τα εξής : Η έννοια της αναδροµής Υλοποίηση και αποδοτικότητα Αφαίρεση της αναδροµής

Διάλεξη 22: Δυαδικά Δέντρα. Διδάσκων: Παναγιώτης Ανδρέου

ΠΛΗ111. Ανοιξη Μάθηµα 4 ο. Στοίβα. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Προγραμματισμός Ι. Δομές Δεδομένων. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΕΠΛ 231 οµές εδοµένων και Αλγόριθµοι Άννα Φιλίππου,

Θεωρητικό Μέρος. int rec(int n) { int n1, n2; if (n <= 5) then return n; else { n1 = rec(n-5); n2 = rec(n-3); return (n1+n2); } }

Βασικές Έννοιες Δοµών Δεδοµένων

ΗΥ240: Δοµές Δεδοµένων Εαρινό Εξάµηνο Ακαδηµαϊκό Έτος 2017 Διδάσκουσα: Παναγιώτα Φατούρου Προγραµµατιστική Εργασία - 1 ο Μέρος

Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών

υναµική έσµευση Μνήµης (συν.) ΕΠΛ 132 Αρχές Προγραµµατισµού ΙΙ 2 Εφαρµογή

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

Διάλεξη 9: Αφηρημένοι Τύποι Δεδομένων. Διδάσκων: Παναγιώτης Ανδρέου

Διάλεξη 17: Δυαδικά Δέντρα. Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Διάλεξη 07: Λίστες Ι Υλοποίηση & Εφαρμογές

Ενότητα 2 Στοίβες Ουρές - Λίστες

Δομές Δεδομένων. Ενότητα 4: Ο ΑΤΔ Λίστα & Υλοποίηση Λίστας με σειριακή αποθήκευση- Ο ΑΤΔ Συνδεδεμένη Λίστα- Υλοποίηση ΑΤΔ Συνδεδεμένη Λίστα με πίνακα

Διάλεξη 15: Δομές Δεδομένων IV (Διπλά Συνδεδεμένες Λίστες)

Τύποι Δεδομένων και Απλές Δομές Δεδομένων. Παύλος Εφραιμίδης V1.0 ( )

διεύθυνση πρώτου στοιχείου διεύθυνση i-οστού στοιχείου T t[n]; &t[0] είναι t &t[i] είναι t + i*sizeof(t)

Διάλεξη 08: Λίστες ΙΙ Κυκλικές Λίστες

υναµικές οµές εδοµένων (συν.) Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα:

Δομές Δεδομένων. Ενότητα 6: Εφαρμογή Συνδεδεμένων Λιστών: Αλφαβητικό ευρετήριο κειμένου- Υλοποίηση ΑΤΔ Στοίβα και Ουρά με δείκτες

Διάλεξη 08: Λίστες ΙΙ Κυκλικές Λίστες

ΛΙΣΤΕΣ. Ορισμός ΑΤΔ Λίστα ΑΤΔ Ακολουθιακή Λίστα Διαχείριση Δεικτών και Λιστών στη C ΑΤΔ Συνδεδεμένη Λίστα. Εφαρμογές και Χρήση Λιστών

Συλλογές, Στοίβες και Ουρές

Κατ οίκον Εργασία 3 Σκελετοί Λύσεων

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διάλεξη 15: Δομές Δεδομένων IV (Διπλά Συνδεδεμένες Λίστες)

Ανάπτυξη και Σχεδίαση Λογισμικού

ΠΛΗ111. Ανοιξη Μάθηµα 7 ο. έντρο. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Διασυνδεδεμένες Δομές. Λίστες. Προγραμματισμός II 1

Δομές Δεδομένων. Καθηγήτρια Μαρία Σατρατζέμη. Τμήμα Εφαρμοσμένης Πληροφορικής. Δομές Δεδομένων. Τμήμα Εφαρμοσμένης Πληροφορικής

Δομές Δεδομένων & Αλγόριθμοι

ιαφάνειες παρουσίασης #5 (β)

Ενότητες 3 & 4: Δένδρα, Σύνολα & Λεξικά Ασκήσεις και Λύσεις

Ενότητα 2 Στοίβες Ουρές - Λίστες

Κατ οίκον Εργασία 3 Σκελετοί Λύσεων

Διδάσκων: Παναγιώτης Ανδρέου

ΠΛΗ111. Ανοιξη Μάθηµα 3 ο. Συνδεδεµένες Λίστες. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

ΗΥ240: Δομές Δεδομένων Εαρινό Εξάμηνο Ακαδημαϊκό Έτος 2018 Διδάσκουσα: Παναγιώτα Φατούρου Προγραμματιστική Εργασία - 1o Μέρος

Ιδιοκτησία Αντικειµένου

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Δυναμική Δέσμευση Μνήμης και Δομές Δεδομένων (Φροντιστήριο)

Στοιχειώδεις Δομές Δεδομένων

Διάλεξη 05: Αφηρημένοι Τύποι Δεδομένων

Sheet2. - Άσκηση 1 οκ - Άσκηση 2 οκ. Σκέψου πώς θα µπορούσες να την

Προγραµµατισµός Ι (ΗΥ120)

lab13grades Άσκηση 2 -Σωστά απελευθερώνετε ολόκληρη τη λίστα και την κεφαλή

Δομές Δεδομένων (Data Structures)

ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 5. Αφηρημένοι Τύποι Δεδομένων / Στοίβες και Ουρές

Δομές Δεδομένων. Ενότητα 7: Άλλες παραλλαγές Συνδεδεμένων Λιστών-Παράσταση Αραιού Πολυωνύμου με Συνδεδεμένη Λίστα. Καθηγήτρια Μαρία Σατρατζέμη

Προγραμματισμός Ι (ΗΥ120)

Οι λίστες, χάνοντας τα πλεονεκτήματα των πινάκων, λύνουν προβλήματα που παρουσιάζουν οι πίνακες

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα με πίνακες. Constructors. Υλοποίηση Στοίβας

ΗΥ240: Δοµές Δεδοµένων Χειµερινό Εξάµηνο Ακαδηµαϊκό Έτος Διδάσκουσα: Παναγιώτα Φατούρου Προγραµµατιστική Εργασία - 1 ο Μέρος

ΕΛΛΗΝΙΚΗ ΔΗΜΟΚΡΑΤΙΑ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ

Ενότητα 7 Ουρές Προτεραιότητας

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διάλεξη 08: ΛίστεςΙΙ Κυκλικές Λίστες. Διδάσκων: Παναγιώτης Ανδρέου

Προγραμματισμός Δομές Δεδομένων

Δομές Δεδομένων. Ενότητα 2: Στοίβες Εισαγωγή-Υλοποίηση ΑΤΔ Στοίβα με Πίνακα-Εφαρμογή Στοίβας: Αντίστροφη Πολωνική Γραφή. Καθηγήτρια Μαρία Σατρατζέμη

Δομές δεδομένων (2) Αλγόριθμοι

Tύπος δεδοµένων (data type) µιας µεταβλητής (σε µια γλώσσα προγραµµατισµού) είναι το σύνολο των τιµών που µπορεί να πάρει η µεταβλητή.

υναµικές οµές εδοµένων

Δείκτες σε συναρτήσεις. Προγραμματισμός II 1

Κατ οίκον Εργασία 2 Σκελετοί Λύσεων

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Διδάσκων: Παναγιώτης Ανδρέου

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Initialize each person to be free. while (some man is free and hasn't proposed to every woman) { Choose such a man m w = 1 st woman on m's list to

Διάλεξη 13: Δομές Δεδομένων ΙΙ (Ταξινομημένες Λίστες)

ΗΥ240: Δομές Δεδομένων Εαρινό Εξάμηνο Ακαδημαϊκό Έτος 2018 Διδάσκουσα: Παναγιώτα Φατούρου Προγραμματιστική Εργασία - 2o Μέρος

Αναδρομικοί Αλγόριθμοι

Απλές Δοµές Δεδοµένων Στην ενότητα αυτή θα γνωρίσουµε ορισµένες απλές Δοµές Δεδοµένων και θα τις χρησιµοποιήσουµε για την αποδοτική επίλυση του προβλή

Δομές Δεδομένων & Αλγόριθμοι

Transcript:

Ενότητα 2: Στοίβες Ουρές - Λίστες Ασκήσεις και Λύσεις Άσκηση 1 Έστω ότι µια βιβλιοθήκη σας παρέχει πρόσβαση σε στοίβες ακεραίων. Η βιβλιοθήκη σας επιτρέπει να ορίσετε µια στοίβα και να καλέσετε τις 5 βασικές λειτουργίες σε αυτή. Για παράδειγµα, ο ορισµός µιας στοίβας (ή µιας ουράς) S1 γίνεται µε τη δήλωση: Stack S1, ενώ υποστηρίζονται οι εξής λειτουργίες: void MakeEmptyStack(stack S) boolean IsEmptyStack(stack S) int Top(Stack S) int Pop(Stack S) void Push(Stack S, int x) Έστω ότι θέλετε να δηµιουργήσετε ένα πρόγραµµα το οποίο απαιτεί επιπρόσθετα των παραπάνω λειτουργιών και την εκτέλεση της λειτουργίας PrintStack(Stack S), η οποία εκτυπώνει όλα τα στοιχεία της στοίβας S. Η εκτέλεση της PrintStack() δεν θα πρέπει να επηρεάζει τη µορφή της στοίβας (δηλαδή η στοίβα θα πρέπει να περιέχει τα ίδια στοιχεία και µε την ίδια σειρά πριν και µετά την εκτέλεση της PrintStack()). Παρουσιάστε ψευδο-κώδικα που θα υλοποιεί την PrintStack(). Υπόδειξη: Επιτρέπεται να χρησιµοποιήσετε µια ή περισσότερες extra στοίβες προκειµένου να υλοποιήσετε τις παραπάνω λειτουργίες. Λύση void PrintStack(Stack S) { int element; Stack tmps; MakeEmptyStack(tmpS); // βοηθητική στοίβα while(!isemptystack(s)){ // ιατρέχουµε τη στοίβα S, εκτελώντας επαναληπτικά την Pop. // Τα στοιχεία που αφαιρούνται από την S τοποθετούνται στην tmps // για να µεταφερθούν και πάλι στην S µετά την περάτωση της εκτύπωσης element = Pop(S); // αφαίρεσε το επόµενο στοιχείο από την S Push(tmpS, element); // τοποθέτησέ το στην στοίβα tmps print(element); // τύπωσε το while (!IsEmptyStack(tmpS)) { element = Pop(tmpS); Push(S, element); // επαναφορά της S στην αρχική της µορφή // αφαίρεσε στοιχείο από την S // τοποθέτησέ το στην S, όπου και υπήρχε αρχικά

Άσκηση 2 ίνεται η ακόλουθη υλοποίηση για αραιούς δυσδιάστατους πίνακες. O αραιός δισδιάστατος πίνακας Α[n][m] υλοποιείται µε έναν boolean δυσδιάστατο πίνακα B[n][m] (κάθε στοιχείο του B έχει την τιµή 0 ή 1) και µια δυναµική συνδεδεµένη λίστα που περιέχει τα µη-µηδενικά στοιχεία του πίνακα Α. Για τον πίνακα Β ισχύουν τα ακόλουθα. Για κάθε i, j, µε 0 i n, 1 j m, B[i][j] = 1 αν και µόνο αν Α[i][j] 0, και Β[i][j] = 0 αν και µόνο αν Α[i][j] = 0. Τα µη-µηδενικά στοιχεία στη λίστα αποθηκεύονται ως εξής: «τα µη-µηδενικά στοιχεία οποιασδήποτε γραµµής i είναι αποθηκευµένα στη λίστα πριν από τα µη-µηδενικά στοιχεία οποιαδήποτε γραµµής j > i και τα µη-µηδενικά στοιχεία οποιασδήποτε στήλης k απαντώνται στη λίστα πριν από τα µη-µηδενικά στοιχεία οποιασδήποτε στήλης m > k». Για παράδειγµα, δίνεται ο αραιός πίνακας Α: 0 7 0 0 0 1 2 0 0 3 0 0 4 0 0 12 0 0 0 0 Ο πίνακας Β που αντιστοιχεί στον Α είναι ο ακόλουθος: και η λίστα έχει την εξής µορφή: 0 1 0 0 0 1 1 0 0 1 0 0 1 0 0 1 0 0 0 0 7 1 2 3 4 12 Παρουσιάστε αλγόριθµο που θα υλοποιεί τη λειτουργία: int Access(int i, int j) η οποία επιστρέφει το στοιχείο στη γραµµή i και στη στήλη j του Α, δεδοµένου ότι ο Α υλοποιείται όπως περιγράφτηκε παραπάνω. Λύση int Search(int i, int j){ int k,l; struct node *p; int cnt = 0; if (i > n OR i < 0 OR j > m OR j < 0) { error(); // το στοιχείο προς πρόσβαση είναι εκτός ορίων πίνακα if (B[i][j]==0) return 0; // το στοιχείο προς πρόσβαση είναι 0

for (k = 0; k < i; k++) { // διατρέχουµε τις γραµµές 0 ως i του B for (l = 0; l < m; l++) // διατρέχουµε όλα τα στοιχεία κάθε τέτοιας γραµµής if (B[k][l] == 1) cnt++; // µετράµε πόσα µη-µηδενικά στοιχεία υπάρχουν σε αυτές τις γραµµές for (l = 0; l < j; l++){ if (B[i][l]) cnt++; // διατρέχουµε τη γραµµή i // και συναθροίζουµε στη cnt τα µη µηδενικά στοιχεία // που προηγούνται του στοιχείου j σε αυτή p = L; while (p!= NULL) { // διατρέχουµε τη λίστα L, στην οποία βρίσκονται τα µη-µηδενικά στοιχεία, // µέχρι να φτάσουµε στο (cnt+1)-οστό στοιχείο της L, // το οποίο αντιστοιχεί στο στοιχείο [i,j] που ζητείται if (cnt == 0) return p->data; p = p->next; cnt--; Άσκηση 3 Υλοποιήστε αλγόριθµο για την διαγραφή στοιχείου από µια ταξινοµηµένη λίστα. Λύση: Node * ListDelete(Node *L, int x) { Node *prev = NULL, *curr = L; // βοηθητικοί δείκτες while(curr!= NULL && curr->data < x){ // όσο δεν έχω διατρέξει όλη τη λίστα // και δεν έχω βρει το στοιχείο prev=curr; // αποθηκεύω δείκτη στο προηγούµενο στοιχείο πριν προχωρήσω τον curr curr=curr->next; // µετακινώ τον curr στο επόµενο στοιχείο της L if (curr == NULL curr->data > x) { // αν δεν υπάρχει το x στη λίστα printf("element x does not exist in L"); return L; if (prev == NULL) // το x είναι το πρώτο στοιχείο της L L = L->next; // αφαίρεσέ το µετακινώντας τον L στο επόµενο στοιχείο else // το x δεν είναι το πρώτο στοιχείο της L prev->next = curr->next; // διαγραφή του x return L; // επιστροφή (ενδεχόµενης) νέας τιµής του δείκτη L

Άσκηση 4 Να παρουσιαστεί υλοποίηση δύο στοιβών, τα στοιχεία των οποίων αποθηκεύονται στον ίδιο πίνακα Α[Ν] (τα στοιχεία του πίνακα είναι τα Α[0],..., Α[Ν-1]). Η υλοποίηση πρέπει να γίνει µε τέτοιο τρόπο ώστε καµία στοίβα να µην υπερχειλίζει παρά µόνο αν το συνολικό πλήθος των στοιχείων και στις δύο στοίβες να ισούται µε n. Όλες οι λειτουργίες στις στοίβες θα πρέπει να εκτελούνται σε χρόνο Θ(1). Λύση Έστω S0 και S1 οι δύο στοίβες. Έστω επίσης ότι τα στοιχεία Length[0] και Length[1] ενός πίνακα Length[] δύο θέσεων περιέχουν το µήκος των στοιβών S1 και S2, αντίστοιχα. Στην υλοποίηση που ακολουθεί, η S1 αυξάνει από αριστερά προς τα δεξιά, ενώ η S2 από δεξιά προς τα αριστερά. Κάθε µια από τις λειτουργίες, παίρνει ως παράµετρο µια ακέραια µεταβλητή which που υποδηλώνει σε ποια στοίβα θα πρέπει να εφαρµοστεί η λειτουργία. Συγκεκριµένα, όταν η which έχει την τιµή 0 (1) η λειτουργία πρέπει να εφαρµοστεί στην S0 (S1, αντίστοιχα). Απλή υλοποίηση (στην οποία οι πίνακες A[] και Length[] είναι καθολικές µεταβλητές). Type A[n]; int Length[2] = {0,0; void MakeEmptyStack(boolean which){ Length[which] = 0; boolean IsEmptyStack(boolean which){ if (Length[which] == 0) return 1; else return 0; Type Top(boolean which){ if (IsEmptyStack(which)) { else if (which==0) return A[Length[which] - 1]; // η S0 αναπτύσσεται από την αρχή του πίνακα προς το τέλος του else return A[N Length[which]]; // η S1 αναπτύσσεται από το τέλος του πίνακα προς της αρχή του // άρα το κορυφαίο στοιχείο της βρίσκεται στη θέση N Length[1] του Α Type Pop(boolean which) { Type x; if (Length[which] == 0) {

x=top(which); // αποθηκεύω στο x το κορυφαίο στοιχείο της στοίβας και Length[which] = Length[which] - 1; // το αφαιρώ, µειώνοντας το µήκος της στοίβας κατά 1 return x; void Push(Type x, boolean which) { if (Length[0] + Length[1] == N) { print( Stack is full ); Length[which] = Length[which] + 1; if (which == 0) A[Length[which] - 1] = x; else A[N - Length[which]] = x; Πιο πολύπλοκη υλοποίηση (στην οποία οι πίνακες A[] και Length[] είναι πεδία ενός struct). typedef struct stack{ int Length[2]; Type A[N]; STACK; pointer MakeEmptyStack(boolean which) { pointer S; // βοηθητικός δείκτης int flag = 0; if (flag == 0) { S=newcell(STACK); flag = 1; S->Length[which] = 0; return S; // η ανάθεση µνήµης πρέπει να γίνει µόνο µια φορά boolean IsEmptyStack(pointer S, boolean which){ if (S->Length[which] == 0) return 1; else return 0; Type Top(pointer S, boolean which){ if (IsEmptyStack(S, which)) { else if (which==0) return (S->A)[S->Length[which] - 1]; else return (S->A)[N S->Length[which]];

Type Pop(pointer S, boolean which){ Type x; if (S->Length[which] == 0) { x = Top(S, which); S->Length[which] = S->Length[which] - 1; return x; void Push(pointer S, Type x, boolean which){ if (S->Length[0] + S->Length[1] == N) { print( Stack is full ); S->Length[which] = S->Length[which] + 1; if (which == 0) (S->A)[S->Length[which] - 1] = x; else (S->A)[N S->Length[which]] = x; Ευχαριστίες Ευχαριστούµε την πρώην βοηθό του µαθήµατος Κατερίνα Τζοµπανάκη για την παραγωγή της ηλεκτρονικής έκδοσης του παραπάνω υλικού.