Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Αγρονόµων Τοπογράφων Μηχανικών Προγραµµατιστικές Τεχνικές Βασίλειος Βεσκούκης ρ. Ηλεκτρολόγος Μηχανικός & Μηχανικός Υπολογιστών ΕΜΠ v.vescoukis@cs.ntua.gr Ρωµύλος Κορακίτης Αστροφυσικός Αναπλ. Καθηγητής ΕΜΠ romylos@survey.ntua.gr Αλγόριθµοι ταξινόµησης (sort) Αλγόριθµοι αναζήτησης (search)
Ταξινόµηση (sort) Μια από τις πιο συνηθισµένες και σηµαντικές διαδικασίες επεξεργασίας δεδοµένων είναι η ταξινόµηση µιας σειράς (λίστας) οµοειδών δεδοµένων, αριθµητικών ή αλφαριθµητικών. Ταξινόµηση (sorting) είναι η διαδικασία µετατροπής µιας λίστας στοιχείων (ενός πίνακα) σε µια ισοδύναµη λίστα όπου τα στοιχεία είναι τοποθετηµένα κατά σειρά, αύξουσα ή φθίνουσα, σύµφωνα µε την τιµή τους. ηλαδή, αν η ταξινοµηµένη λίστα είναι καταχωρηµένη στον πίνακα Α[Ν] ισχύει: Α[0] <= Α[1] <= Α[2] <= <= Α[Ν 2] <= Α[Ν 1] Πολλές µέθοδοι (αλγόριθµοι) έχουν προταθεί για την ταξινόµηση των στοιχείων ενός πίνακα. Βέβαια, οι απλούστεροι αλγόριθµοι είναι λιγότερο αποδοτικοί από τους πιο πολύπλοκους, κάτι που έχει σηµασία όταν το µέγεθος του πίνακα είναι πολύ µεγάλο.
Ταξινόµηση (sort) Παράδειγµα 1: Αρχική λίστα: 43, 22, 17, 36, 16, 28 Ταξινοµηµένη λίστα: 16, 17, 22, 28, 36, 43 (αύξουσα ταξινόµηση) 43, 36, 28, 22, 17, 16 (φθίνουσα ταξινόµηση) Παράδειγµα 2: Αρχική λίστα: Q, W, E, R, T, Y, P Ταξινοµηµένη λίστα: E, P, Q, R, T, W, Y (αύξουσα ταξινόµηση) Στην περίπτωση ταξινόµησης αλφαριθµητικών στοιχείων, ως τιµή του κάθε στοιχείου λαµβάνεται ο αριθµός της κωδικοποίησης του αλφαριθµητικού (συνήθως ASCII). Η ταξινόµηση µιας λίστας έχει µεγάλη σηµασία γιατί διευκολύνει σηµαντικά την αναζήτηση στοιχείων µέσα στην λίστα.
Ταξινόµηση (sort) Όλοι οι αλγόριθµοι ταξινόµησης βασίζονται σε σύγκριση των στοιχείων και σε αντιµετάθεση των στοιχείων, όπου χρειάζεται. Για την ευκολότερη υλοποίηση των αλγορίθµων αυτών είναι πολύ χρήσιµη µια συνάρτηση αντιµετάθεσης στοιχείων, της µορφής: Συνάρτηση Αντιµετάθεση (Πίνακας Α[], δείκτης Κ, δείκτης Μ) Temp = A[K] A[K] = A[M] A[M] = Temp ύο χαρακτηριστικοί αλγόριθµοι ταξινόµησης είναι: Αλγόριθµος επιλογής (selection sort) Αλγόριθµος φυσαλίδας (bubble sort)
Ταξινόµηση µε επιλογή (Selection sort) Ο πίνακας Α[Ν] περιέχει αταξινόµητα δεδοµένα και επιζητούµε αύξουσα ταξινόµηση. Η λειτουργία του αλγορίθµου αυτού είναι: διαδοχική επιλογή του µεγαλύτερου στοιχείου και τοποθέτησή του στο άνω άκρο του πίνακα, το οποίο µειώνεται κατά ένα σε κάθε επανάληψη. ηλαδή: 1 η επανάληψη: Αναζήτηση του µέγιστου των Ν στοιχείων και αντιµετάθεσή του µε το στοιχείο Α[Ν 1] 2 η επανάληψη: Αναζήτηση του µέγιστου των υπολοίπων (Ν 1) στοιχείων και αντιµετάθεσή του µε το στοιχείο Α[Ν 2] 3 η επανάληψη: Αναζήτηση του µέγιστου των υπολοίπων (Ν 2) στοιχείων και αντιµετάθεσή του µε το στοιχείο Α[Ν 3].... (Ν 1) η επανάληψη: Αναζήτηση του µέγιστου των τελευταίων 2 στοιχείων και αντιµετάθεσή του µε το στοιχείο Α[1]
Ταξινόµηση µε επιλογή (Selection sort) ΨΕΥ ΟΚΩ ΙΚΑΣ ΑΡΧΗ Β1 Β2 Β3 Β4 ΤΕΛΟΣ Για Κ = Ν 1 ως 1, βήµα 1, επανάλαβε: Μ = 0 Για Ι = 1 ως Κ, βήµα +1, επανάλαβε: Αν Α[Ι] > Α[Μ], τότε Μ = Ι Τέλος επανάληψης (Ι) Αντιµετάθεσε τις τιµές των Α[Κ] και Α[Μ] Τέλος επανάληψης (Κ)
Ταξινόµηση µε επιλογή (Selection sort) ΠΑΡΑ ΕΙΓΜΑ 1 η επανάληψη (Αρχική λίστα): 43, 22, 17, 36, 16, 28 Μέγιστο : 43 τροποποιηµένη λίστα: 28, 22, 17, 36, 16, 43 2 η επανάληψη : 28, 22, 17, 36, 16, 43 Μέγιστο : 36 τροποποιηµένη λίστα: 28, 22, 17, 16, 36, 43 3 η επανάληψη : 28, 22, 17, 16, 36, 43 Μέγιστο : 28 τροποποιηµένη λίστα: 16, 22, 17, 28, 36, 43 4 η επανάληψη : 16, 22, 17, 28, 36, 43 Μέγιστο : 22 τροποποιηµένη λίστα: 16, 17, 22, 28, 36, 43 5 η επανάληψη : 16, 17, 22, 28, 36, 43 Μέγιστο : 17 ταξινοµηµένη λίστα: 16, 17, 22, 28, 36, 43
Ταξινόµηση φυσαλίδας (Bubble sort) Ο πίνακας Α[Ν] περιέχει αταξινόµητα δεδοµένα και επιζητούµε αύξουσα ταξινόµηση. Η λειτουργία του αλγορίθµου αυτού είναι: επαναληπτικά περάσµατα των στοιχείων του πίνακα έτσι ώστε, σε κάθε πέρασµα, το µεγαλύτερο από τα στοιχεία να σπρώχνεται (µε διαδοχικές συγκρίσεις και αντιµεταθέσεις) προς το άνω άκρο του πίνακα, το οποίο µειώνεται κατά ένα σε κάθε πέρασµα. Η επανάληψη τερµατίζεται όταν εξαντληθούν όλα τα περάσµατα ή όταν σε κάποιο πέρασµα δεν χρειαστεί καµιά αντιµετάθεση στοιχείων.
Ταξινόµηση φυσαλίδας (Bubble sort) ΨΕΥ ΟΚΩ ΙΚΑΣ ΑΡΧΗ Β1 Πέρασµα = 1 Β2 Αντιµετάθεση = ΑΛΗΘΗΣ Β3 Εφ όσον (Πέρασµα < Ν ΚΑΙ Αντιµετάθεση = ΑΛΗΘΗΣ), εκτέλεσε: Αντιµετάθεση = ΨΕΥ ΗΣ Β4 Για Ι = 0 ως (Ν Πέρασµα), βήµα +1, επανάλαβε: Β5 Αν Α[Ι] > Α[Ι + 1], τότε : Αντιµετάθεσε Α[Ι] και Α[Ι + 1] Αντιµετάθεση = ΑΛΗΘΗΣ Τέλος επανάληψης (Ι) Β6 Πέρασµα = Πέρασµα + 1 Β7 Επιστροφή στο Β3 ΤΕΛΟΣ
Ταξινόµηση φυσαλίδας (Bubble sort) ΠΑΡΑ ΕΙΓΜΑ (Αρχική λίστα): 43, 22, 17, 36, 16, 28 1 Ο Πέρασµα: 22, 43, 17, 36, 16, 28 22, 17, 43, 36, 16, 28 22, 17, 36, 43, 16, 28 22, 17, 36, 16, 43, 28 22, 17, 36, 16, 28, 43 2 Ο Πέρασµα: 17, 22, 36, 16, 28, 43 17, 22, 36, 16, 28, 43 17, 22, 16, 36, 28, 43 17, 22, 16, 28, 36, 43 3 ο Πέρασµα: 17, 22, 16, 28, 36, 43 κ.ο.κ. ταξινοµηµένη λίστα: 16, 17, 22, 28, 36, 43
Σύγκριση των αλγορίθµων ταξινόµησης Ο αλγόριθµος επιλογής εκτελεί 1 + 2 + 3 +.. + (Ν 1) συγκρίσεις και, κατά µέσο όρο, Ν/2 αντιµεταθέσεις στοιχείων (που χρειάζονται 3 αναθέσεις τιµής η κάθε µία). Επειδή ισχύει : 1 + 2 + 3 +.. + Ν = Ν(Ν 1) / 2, η µέση επίδοση του αλγορίθµου είναι ανάλογη του Ν 2. Ο αλγόριθµος φυσαλίδας εκτελεί, κατά µέσο όρο, (Ν 1)/2 περάσµατα, Ν/2 συγκρίσεις και Ν/4 αντιµεταθέσεις στο καθένα, εποµένως η επίδοση και αυτού του αλγορίθµου είναι ανάλογη του Ν 2. Χρησιµοποιώντας σύνθετους αλγορίθµους, που χρησιµοποιούν αναδροµή (π.χ. QuickSort) µπορούµε να επιτύχουµε µέση επίδοση ανάλογη του Ν logν, που αποτελεί σηµαντική βελτίωση για µεγάλες τιµές του Ν. Παράδειγµα: Ταξινόµηση πίνακα µε 10 6 στοιχεία µπορεί να απαιτεί 10 12 συγκρίσεις µε αλγόριθµο επιλογής και µόνο 10 7 συγκρίσεις µε αλγόριθµο QuickSort.
Αναζήτηση (search) Μια συνήθης διαδικασία στα στοιχεία ενός πίνακα είναι η αναζήτηση. Αναζήτηση (search) είναι η έρευνα των στοιχείων ενός πίνακα µε σκοπό την εύρεση της θέσης (= δείκτη στοιχείου) που βρίσκεται κάποια συγκεκριµένη τιµή κλειδί (search key) ίδιου τύπου. Η αναζήτηση µπορεί να είναι επιτυχής ή ανεπιτυχής. Ο απλούστερος αλγόριθµος αναζήτησης είναι η γραµµική αναζήτηση (linear or sequential search). Εξετάζουµε, διαδοχικά, όλα τα στοιχεία του πίνακα, συγκρίνοντάς τα µε το κλειδί, µέχρις ότου βρεθεί το στοιχείο που έχει την τιµή κλειδί ή δεν βρεθεί τέτοιο στοιχείο (ανεπιτυχής αναζήτηση). Στην βασική της µορφή, η γραµµική αναζήτηση ΕΝ απαιτεί ταξινοµηµένο πίνακα, όµως η επίδοσή της µπορεί να βελτιωθεί αν ο πίνακας είναι ταξινοµηµένος.
Γραµµική αναζήτηση (Linear search) Αναζητούµε την τιµή key, αν υπάρχει, στα στοιχεία του πίνακα Α[Ν] Στην απλούστερη µορφή, συγκρίνουµε διαδοχικά τα στοιχεία του πίνακα µε την τιµή key µέχρις ότου εξαντληθούν τα στοιχεία ή βρεθεί στοιχείο ίσο µε το key, οπότε ο αλγόριθµος τερµατίζεται. Η τιµή του δείκτη που αναφέρεται στο ζητούµενο στοιχείο καταχωρείται σε µια ακέραια µεταβλητή, π.χ. την Κ. Μετά τον τερµατισµό του αλγορίθµου, αν Κ = 1, τότε η τιµή key ΕΝ υπάρχει στον πίνακα (ανεπιτυχής αναζήτηση). Αν η αναζήτηση είναι επιτυχής, η τιµή του Κ δηλώνει το πρώτο στοιχείο του πίνακα που έχει τιµή key.
Γραµµική αναζήτηση (Linear search) ΨΕΥ ΟΚΩ ΙΚΑΣ ΑΡΧΗ Β1 Επιτυχία = ΨΕΥ ΗΣ Κ = 1 Ι = 0 Β2 Εφ όσον (Ι < Ν ΚΑΙ Επιτυχία = ΨΕΥ ΗΣ), εκτέλεσε: Β3 Αν (Α[Ι] = key), τότε : Επιτυχία = ΑΛΗΘΗΣ Κ = Ι Β4 Ι = Ι + 1 Β5 Επιστροφή στο Β2 ΤΕΛΟΣ
υαδική αναζήτηση (Binary search) Αναζητούµε την τιµή key, αν υπάρχει, στα στοιχεία του ταξινοµηµένου πίνακα Α[Ν] Ο αλγόριθµος αυτός στηρίζεται στην διαδοχική αναζήτηση της τιµής κλεδί key σε υποπίνακες, που ο καθένας έχει εύρος µισό από τον προηγούµενο. Σε κάθε (υπο)πίνακα γίνεται σύγκριση του key µε το µεσαίο στοιχείο του (υπο)πίνακα. Αν υπάρχει ταύτιση τιµών, η αναζήτηση είναι επιτυχής, καταχωρείται ο δείκτης του στοιχείου (π.χ. στην ακέραια µεταβλητή Κ) και ο αλγόριθµος τερµατίζει. Αν το µεσαίο στοιχείο έχει τιµή µεγαλύτερη από το key, αυτό σηµαίνει ότι το ζητούµενο στοιχείο είναι δυνατόν να βρίσκεται στον πρώτο µισό υποπίνακα (µε τιµές µικρότερες του µεσαίου στοιχείου). Αναπροσαρµόζονται τα όρια του υποπίνακα και η αναζήτηση επαναλαµβάνεται στον νέο υποπίνακα, που έχει µέγεθος µισό από τον προηγούµενο. Αντίστοιχα, αν το µεσαίο στοιχείο έχει τιµή µικρότερη από το key, αυτό σηµαίνει ότι το ζητούµενο στοιχείο είναι δυνατόν να βρίσκεται στον δεύτερο µισό υποπίνακα (µε τιµές µεγαλύτερες του µεσαίου στοιχείου). Αναπροσαρµόζονται τα όρια του υποπίνακα και η αναζήτηση επαναλαµβάνεται στον νέο υποπίνακα. Μετά τον τερµατισµό του αλγορίθµου, αν Κ = 1, τότε η τιµή key ΕΝ υπάρχει στον πίνακα. Αλλιώς, η τιµή του Κ δηλώνει το πρώτο στοιχείο του πίνακα που έχει τιµή key.
υαδική αναζήτηση (Binary search) ΨΕΥ ΟΚΩ ΙΚΑΣ ΑΡΧΗ Β1 Επιτυχία = ΨΕΥ ΗΣ Κ = 1 Αριστερά = 0 εξιά = Ν 1 Β2 Εφ όσον (Αριστερά <= εξιά ΚΑΙ Επιτυχία = ΨΕΥ ΗΣ), εκτέλεσε: Μέσον = (Αριστερά + εξιά) / 2 Β3 Αν (Α[Μέσον] = key), τότε : Επιτυχία = ΑΛΗΘΗΣ Κ = Μέσον Β4 Αλλιώς Αν (Α[Μέσον] > key), τότε : εξιά = Μέσον 1 Β5 Αλλιώς Αριστερά = Μέσον + 1 Β6 Επιστροφή στο Β2 ΤΕΛΟΣ
υαδική αναζήτηση (Binary search) ΠΑΡΑ ΕΙΓΜΑ Αναζητούµε τον αριθµό 28 στον ταξινοµηµένο πίνακα (Ν = 13): 16, 17, 22, 28, 36, 43, 49, 55, 69, 72, 73, 88, 91 key = 28 Αρχικές τιµές : Αριστερά = 0, εξιά = 12 (εύρος = 13) 1 η επανάληψη : Μέσον = 6 Α[6] = 49 > 28 Αριστερά = 0, εξιά = 5 (εύρος = 6) 2 η επανάληψη : Μέσον = 2 Α[2] = 22 < 28 Αριστερά = 3, εξιά = 5 (εύρος = 3) 3 η επανάληψη : Μέσον = 4 Α[4] = 36 > 28 Αριστερά = 3, εξιά = 3 (εύρος = 1) 4 η επανάληψη : Μέσον = 3 Α[3] = 28 = 28 Αναζήτηση επιτυχής στο στοιχείο Α[3]
Σύγκριση των αλγορίθµων αναζήτησης Ο αλγόριθµος γραµµικής αναζήτησης χρειάζεται, κατά µέσο όρο, Ν/2 συγκρίσεις όταν η αναζήτηση είναι επιτυχής ή Ν όταν είναι ανεπιτυχής (στην απλή µορφή του). Αντίθετα, ο αλγόριθµος δυαδικής αναζήτησης εκτελεί µόνο µια σύγκριση σε κάθε υποπίνακα. Εποµένως, χρειάζεται το πολύ Π συγκρίσεις, όπου 2 Π 1 <= Ν <= 2 Π. Είναι προφανές ότι η διαφορά είναι πολύ µεγάλη, ιδιαίτερα για µεγάλες τιµές του Ν. Για παράδειγµα, κατά την αναζήτηση ενός στοιχείου σε ένα πίνακα µεγέθους 10 6 µπορεί να απαιτηθούν 500 000 συγκρίσεις µε τον αλγόριθµο γραµµικής αναζήτησης και µόνο 20, το πολύ, συγκρίσεις µε τον αλγόριθµο δυαδικής αναζήτησης.