ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Στοιχειώδεις Δοµές Δεδοµένων Λίστες Κεφάλαιο 3 (3.3, 3.4, 3.7) Ε. Μαρκάκης Επικ. Καθηγητής

Σχετικά έγγραφα
ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Στοιχειώδεις Δοµές Δεδοµένων Λίστες Κεφάλαιο 3 (3.3, 3.4, 3.7) Ε. Μαρκάκης Επικ. Καθηγητής

Δοµές Δεδοµένων. 4η Διάλεξη Στοιχειώδεις Δοµές Δεδοµένων: Πίνακες και Λίστες. Ε. Μαρκάκης

Δοµές Δεδοµένων. 5η Διάλεξη Λίστες και αρχές ανάλυσης αλγορίθµων. Ε. Μαρκάκης

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

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

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

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

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

Γράφημα. Συνδυαστικό αντικείμενο που αποτελείται από 2 σύνολα: Σύνολο κορυφών (vertex set) Σύνολο ακμών (edge set) 4 5 πλήθος κορυφών πλήθος ακμών

Δοµές Δεδοµένων. 2η Διάλεξη Αλγόριθµοι Ένωσης-Εύρεσης (Union-Find) Ε. Μαρκάκης. Βασίζεται στις διαφάνειες των R. Sedgewick K.

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Αλγόριθµοι Ένωσης-Εύρεσης (Union-Find) Κεφάλαιο 1. Ε. Μαρκάκης Επικ. Καθηγητής

Δοµές Δεδοµένων. 9η Διάλεξη Ταξινόµηση - Στοιχειώδεις µέθοδοι. Ε. Μαρκάκης

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Στοιχειώδεις Δοµές Δεδοµένων Δοµικά Στοιχεία και Πίνακες Κεφάλαιο 3 (3.1 και 3.2) Ε. Μαρκάκης Επικ. Καθηγητής

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Πίνακες Συµβόλων Κεφάλαιο 12 ( ) Ε. Μαρκάκης Επίκουρος Καθηγητής

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Ταξινόµηση Mergesort Κεφάλαιο 8. Ε. Μαρκάκης Επίκουρος Καθηγητής

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

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

ΟΙΚΟΝΟΜΙΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. Δοµές Δεδοµένων

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

Δοµές Δεδοµένων. 7η Διάλεξη Αφηρηµένοι Τύποι Δεδοµένων. Ε. Μαρκάκης

Δομές ελέγχου ροής προγράμματος

Δοµές Δεδοµένων. 3η Διάλεξη Στοιχειώδεις Δοµές Δεδοµένων: Πίνακες. Ε. Μαρκάκης

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

Δοµές Δεδοµένων. 13η Διάλεξη Πίνακες Συµβόλων. Ε. Μαρκάκης

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

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Εξωτερική Αναζήτηση και Β-δέντρα Κεφάλαιο 16. Ε. Μαρκάκης Επίκουρος Καθηγητής

Δοµές Δεδοµένων. 18η Διάλεξη Ισορροπηµένα δέντρα. Ε. Μαρκάκης

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

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Ουρές προτεραιότητας Κεφάλαιο 9. Ε. Μαρκάκης Επίκουρος Καθηγητής

Δοµές Δεδοµένων. 10η Διάλεξη Ταξινόµηση. E. Μαρκάκης

4. Συνδεδεμένες Λίστες

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

Δοµές Δεδοµένων. 8η Διάλεξη: Ταξινόµηση. Ε. Μαρκάκης

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

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

Δοµές Δεδοµένων. 14η Διάλεξη Δέντρα Δυαδικής Αναζήτησης. Ε. Μαρκάκης

ΟΙΚΟΝΟΜΙΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ. Δοµές Δεδοµένων

Oι βασικές πράξεις (λειτουργίες) που ορίζονται για τον τύπο στοίβα αναφέρονται παρακάτω:

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

Δοµές Δεδοµένων. 11η Διάλεξη Ταξινόµηση Quicksort και Ιδιότητες Δέντρων. Ε. Μαρκάκης

Δομές Δεδομένων & Ανάλυση Αλγορίθμων. 3ο Εξάμηνο. Ουρά (Queue) Υλοποίηση της με τη βοήθεια πίνακα.

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

Δοµές Δεδοµένων. 6η Διάλεξη Αναδροµικές Εξισώσεις και Αφηρηµένοι Τύποι Δεδοµένων. Ε. Μαρκάκης

ΠΑΡΑΡΤΗΜΑ: QUIZ ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ

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

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

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

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Ουρές προτεραιότητας Κεφάλαιο 9. Ε. Μαρκάκης Επίκουρος Καθηγητής

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

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

Βασικάχαρακτηριστικάτηςγλώσσας. Πίνακες, Έλεγχος Ροής και Βρόχοι

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

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java

Sheet2. Σωστή, και µπράβο που µεριµνήσατε για λίστες διαφορετικών µεγεθών.

ΕΝΟΤΗΤΑ 6 ΛΙΣΤΕΣ ΠΑΡΑΛΕΙΨΗΣ (SKIP LISTS)

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

Κλάσεις και Αντικείµενα

Δοµές Δεδοµένων. 16η Διάλεξη Κατακερµατισµός. Ε. Μαρκάκης

Διάλεξη 12: Δέντρα ΙΙ Δυαδικά Δέντρα

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

Αλγόριθμοι Ταξινόμησης Μέρος 1

for for for for( . */

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

Κεφάλαιο 10 Ψηφιακά Λεξικά

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

ΠΛΗΡΟΦΟΡΙΑΚΑ & ΤΗΛΕΠΙΚΟΙΝΩΝΙΑΚΑ ΣΥΣΤΗΜΑΤΑ

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

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

2.1. Εντολές Σχόλια Τύποι Δεδομένων

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

Δοµές Δεδοµένων. 17η Διάλεξη Ισορροπηµένα δέντρα. Ε. Μαρκάκης

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

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

Δυαδικά Δένδρα Αναζήτησης, Δένδρα AVL

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

Λίστες παράλειψης (skip lists)

Σύνοψη Προηγούμενου. Λίστες (Lists) Συνδεδεμένες Λίστες: Εισαγωγή (1/2) Συνδεδεμένες Λίστες. Ορέστης Τελέλης

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

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ. Ταξινόµηση - Στοιχειώδεις µέθοδοι Κεφάλαιο 6. Ε. Μαρκάκης Επίκουρος Καθηγητής

Αντικειµενοστρεφής Προγραµµατισµός

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

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Constructors, equals, tostring

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

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

ΠΛΗΡΟΦΟΡΙΚΗ Ι JAVA Τμήμα θεωρίας με Α.Μ. σε 3, 7, 8 & 9 6/12/07

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

Επιλογές και Κριτήρια Σχεδιασμού ΑΤΔ Ανεξαρτήτως από Γλώσσα Υλοποίησης 24/4/2012

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java II

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

Αντικείµενα. ηµιουργία και χρησιµοποίηση αντικειµένων. ηµιουργία αντικειµένων

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

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

I (JAVA) Ονοματεπώνυμο: Α. Μ.: Δώστε τις απαντήσεις σας ΕΔΩ: Απαντήσεις στις σελίδες των ερωτήσεων ΔΕΝ θα ληφθούν υπ όψην.

Διάλεξη 14: Δομές Δεδομένων ΙΙI (Λίστες και Παραδείγματα)

Βασικά Στοιχεία της Java

Οργάνωση αρχείων: πως είναι τοποθετηµένες οι εγγραφές ενός αρχείου όταν αποθηκεύονται στο δίσκο

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

Transcript:

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ Στοιχειώδεις Δοµές Δεδοµένων Λίστες Κεφάλαιο 3 (3.3, 3.4, 3.7) Ε. Μαρκάκης Επικ. Καθηγητής

Περίληψη Συνδεδεµένες λίστες είδη λιστών Παραδείγµατα µε επεξεργασία λιστών Συµβάσεις αρχής και τέλους Τάξη κυκλικής λίστας Διπλά συνδεδεµένες λίστες Αναπαράσταση γράφων µε λίστες Δοµές Δεδοµένων 04-2

Συνδεδεµένες λίστες Δοµές Δεδοµένων 04-3

Συνδεδεµένες λίστες Συνδεδεµένη λίστα Συλλογή δυναµικά κατανεµηµένων κόµβων Κάθε κόµβος περιέχει κάποια στοιχεία Κάθε κόµβος περιέχει συνδέσεις προς άλλους κόµβους Ευµετάβλητη δοµή µε πολλές εφαρµογές Απλή εισαγωγή και αφαίρεση στοιχείων Δεν επιτρέπει όµως τυχαία προσπέλαση κόµβων (π.χ. εύρεση του k-οστού στη σειρά στοιχείου απαιτεί προσπέλαση των πρώτων k στοιχείων) Εναλλακτική λύση σε σχέση µε πίνακα Η καλύτερη λύση εξαρτάται από το πρόβληµα Δοµές Δεδοµένων 04-4

Συνδεδεµένες λίστες Τύποι συνδεδεµένων λιστών Λίστες µονής σύνδεσης Λίστες διπλής (ή πολλαπλής) σύνδεσης Κυκλικές λίστες µονής σύνδεσης Κυκλικές λίστες διπλής (ή πολλαπλής) σύνδεσης Δοµές Δεδοµένων 04-5

Συνδεδεµένες λίστες Λίστες µονής σύνδεσης Λίστες διπλής σύνδεσης Κυκλικές λίστες Κυκλικές λίστες διπλής σύνδεσης Δοµές Δεδοµένων 04-6

Συνδεδεµένες λίστες Λίστα µονής σύνδεσης Κάθε κόµβος περιέχει έναν κόµβο (ως σύνδεσµο προς τον επόµενό του) Αυτοαναφορικές (self-referent) δοµές Παριστάνει µία ακολουθία στοιχείων Ορισµός κόµβου λίστας απλής σύνδεσης Μπορεί να περιέχει οποιοδήποτε αντικείµενο class Node{ Object item; // ή ό,τι άλλο αντικείµενο θέλετε Node next; Node(Object v){ item = v; next = null; } } Δηµιουργία ενός νέου κόµβου Node x = new Node(v); Καλή τεχνική να ανατίθενται αρχικές τιµές σε όλα τα στοιχεία Δοµές Δεδοµένων 04-7

Συνδεδεµένες λίστες Διαγραφή από συνδεδεµένη λίστα Για να διαγράψουµε ένα αντικείµενο στο εσωτερικό µιας λίστας µονής σύνδεσης, θα πρέπει να έχουµε πρόσβαση στο ακριβώς προηγούµενο αντικείµενο µέσα στη λίστα Έστω ότι η µεταβλητή x δείχνει στο προηγούµενο αντικείµενο από αυτό που θέλουµε να διαγράψουµε Αφαίρεση του κόµβου που ακολουθεί την x Node t = x.next; x.next = t.next; Εναλλακτικά (χωρίς extra δείκτη t) x.next = x.next.next Δοµές Δεδοµένων 04-8

Συνδεδεµένες λίστες Εισαγωγή σε συνδεδεµένη λίστα Έστω ότι θέλουµε να εισάγουµε ένα αντικείµενο στο εσωτερικό της λίστας Πάλι θέλουµε πρόσβαση στο αντικείµενο που θα είναι πίσω από αυτό που θα εισάγουµε Εισαγωγή του Node t µετά τον x t.next = x.next; x.next = t; Προσοχή! Διαφορετικός κώδικας απαιτείται όταν οι εισαγωγές/διαγραφές είναι στην αρχή µιας λίστας Δοµές Δεδοµένων 04-9

Συνδεδεµένες λίστες Εντοπισµός του n-οστού κόµβου, για n 1 Δεν υπάρχει άµεση µέθοδος Αναγκαστικά διατρέχουµε τη λίστα Π.χ. αν το x δείχνει στην κεφαλή της λίστας, τότε: for (int i = 1; i < n; i++) if (x.next!=null) x = x.next; Δοµές Δεδοµένων 04-10

Συνδεδεµένες λίστες Συνηθισµένα λάθη κατά την επεξεργασία λιστών Χρήση αόριστης αναφοράς (προς αντικείµενο που δεν έχει οριστεί) Χρήση αναφοράς προς λάθος αντικείµενο Χρήση πεδίου ενός null κόµβου (π.χ. δεν µπορούµε να χρησιµοποιήσουµε το x.next όταν x=null) Γενική συµβουλή προς αποφυγή λαθών Δείτε πρώτα σχηµατικά πώς πρέπει η µέθοδος που θέλετε να υλοποιήσετε να µεταβάλει τις αναφορές στους εµπλεκόµενους κόµβους Δοµές Δεδοµένων 04-11

Λίστες ή πίνακες; Κατανάλωση χώρου Πίνακας: fixed µε τη δηµιουργία Λίστα: ανάλογος του αριθµού των στοιχείων Χρειάζεται χώρος και για τους δείκτες Χρόνος εισαγωγής / εξαγωγής Πίνακας: πιθανή µετακίνηση στοιχείων (π.χ. σε ταξινοµηµένους πίνακες) Λίστα: δεν χρειάζονται µετακινήσεις Χρόνος εύρεσης k-οστού στοιχείου Πίνακας: κατευθείαν πρόσβαση στο a[k] Λίστα: διατρέχουµε τους προηγούµενους κόµβους Δοµές Δεδοµένων 04-12

Επεξεργασία λιστών Παράδειγµα 1: Αντιστροφή λίστας µονής σύνδεσης Είσοδος: ο δείκτης της κεφαλής µίας λίστας Έξοδος: η ίδια λίστα µε αντιστραµµένη σειρά στους κόµβους Ιδέα: διατρέχω τη λίστα και διατηρώ 3 δείκτες r: προηγούµενος κόµβος (που έχω ήδη επεξεργαστεί στην προηγούµενη επανάληψη), y: τρέχων κόµβος, t: επόµενος κόµβος Δοµές Δεδοµένων 04-13

Επεξεργασία λιστών Αντιστροφή λίστας µονής σύνδεσης Ερµηνεία: r: προηγούµενος κόµβος, y: τρέχων κόµβος, t: επόµενος κόµβος static Node reverse(node x) { Node t, y = x, r = null; while (y!= null) { t = y.next;//t στον επόµενο y.next = r;//αντιστροφή r = y;//r, y 1 βήµα µπροστά y = t; } return r; } Δοµές Δεδοµένων 04-14

Επεξεργασία λιστών Παράδειγµα 2: ταξινόµηση µε εισαγωγή (insertion sort) Είσοδος: Ένα σύνολο ακεραίων που εισάγει ο χρήστης (ας υποθέσουµε ότι είναι όλοι θετικοί ακέραιοι) Έξοδος: Μία λίστα µε τα ίδια στοιχεία αλλά ταξινοµηµένα σε αύξουσα σειρά π.χ. µε είσοδο θέλουµε έξοδο: 37 12 15 15 Δοµές Δεδοµένων 04-15

Χρήση δύο λιστών a: µη ταξινοµηµένη, δηµιουργείται όταν διαβάζουµε την είσοδο b: ταξινοµηµένη (αρχικά κενή) Μεταφορά κόµβων Διατρέχουµε την a Αφαιρούµε ένα στοιχείο από την a Βρίσκουµε τη σωστή θέση στη b Εισάγουµε το στοιχείο στη b High Level Idea Χρήση (ψευδο)-κόµβου κεφαλής Βρίσκεται στην αρχή, δεν περιέχει στοιχεία Τοποθετείται µόνο για να διευκολύνει την επεξεργασία Δοµές Δεδοµένων 04-16

Επεξεργασία λιστών Ταξινόµηση µε εισαγωγή (1/2) class ListSortExample { static class Node { int val; Node next; Node(int v, Node t) { val = v; next = t; } } static Node create() { Node a = new Node(0, null); // ψευδοκόµβος for (In.init();!In.empty(); ) a.next = new Node(In.getInt(), a.next); return a; } // Δηµιουργία λίστας µε κεφαλή a static void print(node h) { } for (Node t = h.next; t!= null; t = t.next) Out.println(t.val + ""); } Δοµές Δεδοµένων 04-17

Επεξεργασία λιστών Ταξινόµηση µε εισαγωγή (2/2) static Node sort(node a) { Node t, u, x, b = new Node(0, null); //t = κόµβος που φέυγει από την a για να πάει στην b while (a.next!= null) { //πρώτα διαγράφουµε τον επόµενο κόµβο από την a return b; } t = a.next; u = t.next; a.next = u; for (x = b; x.next!= null; x = x.next) if (x.next.val > t.val) break; t.next = x.next; //εισαγωγή στην b x.next = t; } public static void main(string[] args) { print(sort(create())); } } Δοµές Δεδοµένων 04-18

Παρατηρήσεις Θα µπορούσαµε και µε µία µόνο λίστα (η λίστα a δεν είναι απαραίτητη). Όταν διαβάζουµε ένα στοιχείο, µπορούµε να το βάλουµε κατευθείαν στη σωστή θέση της b Σε άλλες εφαρµογές όµως ίσως χρειάζεται µία µέθοδος σαν την create() για να διαβάσουµε πρώτα όλη την είσοδο Πολυπλοκότητα? Στη χειρότερη περίπτωση διατρέχουµε όλη την τρέχουσα λίστα b κάθε φορά 1+ 2+...+ Ν-1 = Ν(Ν-1)/2 (τάξη µεγέθους Ν 2 ) Θα επανέλθουµε αργότερα για την πολυπλοκότητα της ταξινόµησης Δοµές Δεδοµένων 04-19

Επεξεργασία λιστών Παράδειγµα 3: Χρήση κυκλικής λίστας Το πρόβληµα του Josephus Titus Flavius Josephus (37 100 µ. Χ.) Πολιορκία της πόλης Yodfat (περίπου 67 µ. Χ.) N άτοµα τοποθετούνται σε έναν κύκλο Αφαιρούµε το M-οστό άτοµο, για κάποιο δοσµένο Μ (ξεκινώντας από το 1) Έπειτα, ξεκινώντας από το Μ+1 αφαιρούµε πάλι το Μ- οστό άτοµο κ.ο.κ. µέχρι να µείνει µόνο ένα άτοµο Josephus(N,M): το άτοµο που θα µείνει στο τέλος Δοµές Δεδοµένων 04-20

Επεξεργασία λιστών Άµεση λύση µε χρήση κυκλικής λίστας Κατασκευή λίστας N κόµβων Ο τελευταίος κόµβος δείχνει στον πρώτο Διατρέχουµε τη λίστα µέχρι να αδειάσει Κυκλική διάσχιση χωρίς ειδικό κώδικα Διαγράφουµε το M-οστό στοιχείο κάθε φορά Εύκολη αφαίρεση στοιχείων ακολουθώντας δείκτες Δοµές Δεδοµένων 04-21

class Josephus { static class Node { Επεξεργασία λιστών int val; Node next; Node(int v) { val = v; } } public static void main(string[] args) { int N = Integer.parseInt(args[0]); int M = Integer.parseInt(args[1]); Node t = new Node(1); Node x = t; //t στην αρχή for (int i = 2; i <= N; i++) { x.next = new Node(i); x = x.next} x.next = t;//τελευταίος κόµβος δείχνει την αρχή while (x!= x.next) { for (int i = 1; i < M; i++) x = x.next; x.next = x.next.next; } //διαγραφή Out.println("Survivor is " + x.val); } } Δοµές Δεδοµένων 04-22

Υλοποίηση του Josephus µε πίνακες Γενικά µπορούµε να υλοποιούµε λίστες µε πίνακες (δεν είναι πάντα βολικό όµως) Χρειαζόµαστε 2 πίνακες: val[i]: στοιχείο κόµβου i next[i]: δείκτης επόµενου κόµβου Διαγραφή κόµβου γίνεται µε ενηµέρωση του next[] next[x] = next[next[x]] Δοµές Δεδοµένων 04-23

Συµβάσεις αρχής και τέλους Μερικές φορές βολεύει να κάνουµε κάποιες συµβάσεις για τις λίστες µε τις οποίες δουλεύουµε Συνήθως αφορούν την αρχή ή το τέλος της λίστας, καθώς και το αν επιτρέπεται να είναι κενή µια λίστα Π.χ. χρήση ψευδοκόµβων στην αρχή ή στο τέλος Οι λόγοι είναι καθαρά προγραµµατιστικοί Οµοιοµορφία στον κώδικα Πιο βολική υλοποίηση µεθόδων, χωρίς πρόσθετο κώδικα για την αρχή ή το τέλος Συνήθως δεν επηρεάζεται η συνολική πολυπλοκότητα του προγράµµατος µε τέτοιες συµβάσεις Δοµές Δεδοµένων 04-24

Συµβάσεις αρχής και τέλους Κυκλική, ποτέ κενή πρώτη εισαγωγή: head.next = head; εισαγωγή του t µετά το x: t.next = x.next; x.next=t; αφαίρεση µετά το x: x.next = x.next.next βρόχος διέλευσης: t = head; do { t = t.next;} while (t!= head) έλεγχος αν έχει ένα στοιχείο: if (head.next == head) Σύµβαση 1η: κυκλική λίστα Η λίστα δεν είναι ποτέ κενή Το head δείχνει στην «αρχή» της λίστας Δοµές Δεδοµένων 04-25

Συµβάσεις αρχής και τέλους Λίστα µονής σύνδεσης, αναφορά κεφαλής, null στην ουρά της λίστας ανάθεση αρχικών τιµών: head = null; εισαγωγή του t µετά το x: if (x == null) { head = t; head.next = null;} else { Σύµβαση 2η: χωρίς ψευδο-κόµβους Απλούστερη µορφή λίστας Πιθανόν ειδικός κώδικας για αρχή και τέλος t.next = x.next; x.next = t; } αφαίρεση µετά το x: t = x.next; x.next = t.next; βρόχος διέλευσης: for (t=head; t!=null; t=t.next) έλεγχος αν είναι κενή: if (head == null) Δοµές Δεδοµένων 04-26

Συµβάσεις αρχής και τέλους Ψευδο-κόµβος κεφαλής, null στην ουρά της λίστας ανάθεση αρχικών τιµών: head = new Node(); head.next = null; εισαγωγή του t µετά το x: t.next = x.next; x.next = t; αφαίρεση µετά το x: t = x.next; x.next = t.next; βρόχος διέλευσης: for (t=head.next; t!=null; t=t.next) έλεγχος αν είναι κενή: if (head.next == null) Σύµβαση 3η: ψευδο-κόµβος κεφαλής Δεν χρειάζεται ειδικός κώδικας στην εισαγωγή Υπάρχει πάντα κάποιος κόµβος στη λίστα Δοµές Δεδοµένων 04-27

Συµβάσεις αρχής και τέλους Ψευδο-κόµβοι κεφαλής και ουράς ανάθεση αρχικών τιµών: head = new Node(); z = new Node(); head.next = z; z.next = z; εισαγωγή του t µετά το x: t.next = x.next; x.next = t; αφαίρεση µετά το x: x.next = x.next.next; βρόχος διέλευσης: for (t=head.next; t!=z; t=t.next) έλεγχος αν είναι κενή: if (head.next == z) Σύµβαση 4η: ψευδο-κόµβος κεφαλής και ουράς Τουλάχιστον δύο κόµβοι από τη στιγµή της δηµιουργίας και έπειτα Ο τελευταίος κόµβος δείχνει στον εαυτό του Δοµές Δεδοµένων 04-28

Παρατηρήσεις 1. Το τι είδους λίστα ή σύµβαση θα χρησιµοποιήσετε εξαρτάται πάντα από το πρόβληµα 2. Συλλογή σκουπιδιών Στη Java δεν χρειάζεται να απελευθερώνουµε τη µνήµη όταν σταµατάµε να χρησιµοποιούµε κάποιο δείκτη. Γίνεται αυτόµατα από τον Garbage Collector Σε άλλες γλώσσες πρέπει να γίνει ρητά (στη C++ καλώντας την delete). Προσοχή στη χρήση της µνήµης! Δοµές Δεδοµένων 04-29

Κλάσεις λιστών Μέχρι τώρα, χρησιµοποιήσαµε ως δοµικό στοιχείο για να φτιάχνουµε λίστες την κλάση Node Μπορούµε για κάθε τύπο λίστας, να ορίσουµε µία κλάση που να περιέχει όλες τις χρήσιµες µεθόδους ως µέλη Πιο δοµηµένος προγραµµατισµός Κάνει πιο εύκολο τον κώδικα για προγράµµατα-πελάτες. Οι έλεγχοι γίνονται από τις µεθόδους της κλάσης Π.χ. για λίστα µονής σύνδεσης, χρειαζόµαστε µεθόδους για να παίρνουµε την αναφορά του πεδίου next, για την εισαγωγή νέου κόµβου, για τη διαγραφή, κτλ Δοµές Δεδοµένων 04-30

Παράδειγµα: Κλάση κυκλικής λίστας Όλες οι λειτουργίες υλοποιούνται από την κλάση class CircularList { } static class Node { } int val; Node next; Node(int v) { val = v; } Node next(node x) { return x.next; } int val(node x) { return x.val; } Node insert(node x, int v) { //εισαγωγή µετά το x Node t = new Node(v); if (x == null) t.next = t; else { t.next = x.next; x.next = t; } return t; }//επιστρέφει κόµβο τελευταίας εισαγωγής void remove(node x) { x.next = x.next.next; } Δοµές Δεδοµένων 04-31

Κλάση κυκλικής λίστας Συνάρτηση του Josephus µε την κλάση κυκλικής λίστας Πολύ απλούστερος κώδικας χάρη στις έτοιµες µεθόδους class JosephusY { public static void main(string[] args) { int N = Integer.parseInt(args[0]); int M = Integer.parseInt(args[1]); CircularList L = new CircularList(); CircularList.Node x = null; for (int i = 1; i <= N; i++) x = L.insert(x, i);//x δείχνει τελευταίο κόµβο while (x!= L.next(x)) { for (int i = 1; i < M; i++) x = L.next(x); L.remove(x); } Out.println("Survivor is " + L.val(x)); } } Δοµές Δεδοµένων 04-32

Διπλά συνδεδεµένη λίστα Διπλά συνδεδεµένη λίστα 2 δείκτες σε κάθε κόµβο Κάθε κόµβος δείχνει και στον προηγούµενο Κίνηση προς δύο κατευθύνσεις Ευκολότερη εισαγωγή και διαγραφή Εισαγωγή: αρκεί να έχουµε δείκτη προς προηγούµενο ή επόµενο κόµβο Διαγραφή: αρκεί ο προς διαγραφή κόµβος Μεγαλύτερο κόστος συντήρησης Διπλάσιοι σύνδεσµοι προς ενηµέρωση Μεγαλύτερο κόστος µνήµης Διπλάσιοι σύνδεσµοι προς αποθήκευση Δοµές Δεδοµένων 04-33

Διπλά συνδεδεµένη λίστα Δήλωση διπλά συνδεδεµένης λίστας class Node{ Object item; Node next; Node prev; Node(Object v){ } } item = v; next = null; prev = null; Διαγραφή του κόµβου t Δεν χρειάζονται δείκτες σε άλλους κόµβους t.next.prev = t.prev; t.prev.next = t.next; Δοµές Δεδοµένων 04-34

Διπλά συνδεδεµένη λίστα Εισαγωγή του κόµβου t Αρκεί να έχουµε τον προηγούµενο ή επόµενο Έστω ότι δίνεται ο προηγούµενος x t.next = x.next; x.next.prev = t; x.next = t; t.prev = x; Έστω ότι δίνεται ο επόµενος y t.prev = y.prev; y.prev.next = t; y.prev = t; t.next = y; Δοµές Δεδοµένων 04-35

Επιστροφή στην Αναπαράσταση Γράφων Γράφος (graph): (V, E) V: Ένα σύνολο από κόµβους E: Πλευρές (σύνδεσµοι µεταξύ κόµβων) Αν έχουµε Ν κόµβους, τους ονοµατίζουµε συνήθως από 0 ως Ν-1 Πίνακας γειτνίασης Συµµετρικός πίνακας ΝxΝ Αν (i, j) E, a[i][j] = a[j][i] = 1 Διαφορετικά a[i][j] = a[j][i] = 0 Από σύµβαση θέτουµε a[i][i] = 1 i Χώρος µνήµης: Ν 2 Χρόνος για να δούµε αν συνδέονται 2 κορυφές: σταθερός, ανεξάρτητος από Ν (1 εντολή) Δοµές Δεδοµένων 04-36

Δηµιουργία πίνακα γειτνίασης class AdjacencyMatrix { //διαβάζει πλευρές από είσοδο } } public static void main(string[] args) { int Ν = Integer.parseInt(args[0]); int E = Integer.parseInt(args[1]); boolean adj[][] = new boolean[ν][ν]; for (int i = 0; i < Ν; i++) for (int j = 0; j < Ν; j++) adj[i][j] = false; for (int i = 0; i < Ν; i++) adj[i][i] = true; for (In.init();!In.empty() ;) { } int i = In.getInt(), j = In.getInt(); adj[i][j] = true; adj[j][i] = true; Δοµές Δεδοµένων 04-37

Αναπαράσταση µε λίστες γειτνίασης Εναλλακτική αναπαράσταση: Διατηρούµε έναν πίνακα µε λίστες Μία λίστα για κάθε κορυφή (λίστα γειτνίασης) Περιέχει όλες τις άλλες κορυφές που συνδέονται µαζί της Χώρος µνήµης: Ν + 2 Ε (συµφέρει αν Ε << Ν 2 ) Για αραιούς γράφους πολύ προτιµότερη η χρήση λίστας αντί πίνακα Χρόνος για να δούµε αν συνδέονται 2 κορυφές: πρέπει να διατρέξουµε τη λίστα της µίας εκ των 2 κορυφών, στη χειρότερη περίπτωση: Ο(Ν) Δοµές Δεδοµένων 04-38

Δηµιουργία λιστών γειτνίασης class AdjacencyLists { static class Node { int v; Node next; } Node (int v, Node t) { this.v = v; next = t; } public static void main(string[] args) { int Ν = Integer.parseInt(args[0]); int E = Integer.parseInt(args[1]); Node adj[] = new Node[Ν]; for (int i = 0; i < Ν; i++) adj[i] = null;//αρχικά όλες null for (In.init();!In.empty() ;) { int i = In.getInt(), j = In.getInt(); adj[j] = new Node(i, adj[j]); //εισαγωγή µπροστά adj[i] = new Node(j, adj[i]); } } } Δοµές Δεδοµένων 04-39