Class Hub
Data structures·Διάλεξη 10·~36 min

L10 · Δομές Δεδομένων — Σωροί & Ξένα Σύνολα

Τι θα δούμε

Στο L09 αφήσαμε δύο υποσχέσεις. Είπαμε ότι ο Dijkstra και ο Prim τρέχουν σε «με έναν δυαδικό σωρό», και ότι ο Kruskal χρειάζεται μια δομή που απαντά γρήγορα «είναι αυτές οι δύο κορυφές ήδη συνδεδεμένες;». Και στις δύο περιπτώσεις είπαμε «θα το δούμε αργότερα».

Αυτή είναι η διάλεξη του «αργότερα». Δύο δομές δεδομένων:

  1. Σωρός (heap) — υλοποιεί μια ουρά προτεραιότητας: «δώσε μου το μικρότερο στοιχείο» σε . Αυτό κάνει γρήγορους τον Dijkstra και τον Prim.
  2. Ξένα σύνολα (union-find) — απαντά «σε ποιο σύνολο ανήκει το ;» και «ένωσε δύο σύνολα» σχεδόν σε σταθερό χρόνο. Αυτό κάνει γρήγορο τον Kruskal.

Μέρος Α' — Σωροί (Heaps)

Το πρόβλημα που λύνουν

Φαντάσου μια συλλογή στοιχείων με κλειδιά (αριθμούς) όπου ρωτάς ξανά και ξανά: «ποιο είναι το μικρότερο;» — και μετά το βγάζεις από τη συλλογή. Αυτό ακριβώς κάνει ο Dijkstra: σε κάθε βήμα βγάζει την ανεξερεύνητη κορυφή με το μικρότερο .

Ποιες είναι οι επιλογές μας;

ΔομήFindMinInsert / Delete
Μη ταξινομημένος πίνακας — σάρωσε όλα
Ταξινομημένος πίνακας — είναι στην άκρη — μετατόπιση
Σωρός

Ορισμός

Ο ορισμός έχει δύο ανεξάρτητα κομμάτια:

  • «Ισοσταθμισμένο δυαδικό δέντρο» — αφορά το σχήμα. Κάθε επίπεδο γεμίζει πλήρως πριν αρχίσει το επόμενο, και το τελευταίο γεμίζει από αριστερά. Αυτό εγγυάται ύψος — εκεί κρύβεται το κάθε πράξης.
  • «Ιδιότητα διάταξης» — αφορά τα κλειδιά: κάθε γονιός κάθε παιδί του.

Πρόσεξε τι δεν λέει η ιδιότητα: τίποτα για τη σχέση ανάμεσα σε αδέλφια, ούτε ανάμεσα σε κορυφές διαφορετικών κλάδων. Ο σωρός είναι «χαλαρά» ταξινομημένος — και ακριβώς γι' αυτό συντηρείται φθηνά. Άμεση συνέπεια: η ρίζα έχει πάντα το ελάχιστο κλειδί, οπότε FindMin .

Αναπαράσταση με πίνακα

Το ωραιότερο κόλπο: ο σωρός δεν χρειάζεται δείκτες. Αφού το σχήμα είναι αυστηρά ισοσταθμισμένο, αποθηκεύουμε τις κορυφές σε έναν πίνακα , επίπεδο-επίπεδο από αριστερά προς δεξιά. Τότε για κάθε θέση :

«Κατέβα στο παιδί» = πολλαπλασίασε με 2· «ανέβα στον γονέα» = διαίρεσε με 2. Καθαρή αριθμητική, μηδέν δείκτες.

Αυτό ακούγεται αφηρημένο μέχρι να το πιάσεις στα χέρια σου. Πάτησε οποιοδήποτε στοιχείο παρακάτω — δέντρο ή πίνακα — και δες τον γονέα και τα παιδιά του να βγαίνουν από τους τρεις τύπους, για το συγκεκριμένο που διάλεξες:

Ο σωρός ΕΙΝΑΙ ο πίνακας — δείκτες από καθαρή αριθμητική
H[4] = 9

Πάτησε οποιονδήποτε κόμβο του δέντρου ή κελί του πίνακα — ο γονέας ⌊i/2⌋ και τα παιδιά 2i, 2i+1 ανάβουν ταυτόχρονα και στις δύο όψεις.

2i = 15i = 28i = 39i = 411i = 514i = 618i = 720i = 821i = 913i = 10
Γονέας — ⌊i/2⌋
⌊4/2⌋ = 2
H[2] = 5
Αριστερό παιδί — 2i
2·4 = 8
H[8] = 20
Δεξί παιδί — 2i+1
2·4+1 = 9
H[9] = 21
Επιλεγμένο: H[4] = 9. Ο γονέας του είναι στη θέση ⌊4/2⌋ = 2: το H[2] = 5. Παιδιά: αριστερό στο 2·4 = 8 (H[8] = 20), δεξί στο 2·4+1 = 9 (H[9] = 21).

Δοκίμασε ένα φύλλο (π.χ. το ): το ξεπερνά το , άρα «δεν υπάρχει παιδί» — έτσι ακριβώς ξέρει ο αλγόριθμος ότι έφτασε στον πάτο. Και πρόσεξε ότι κάθε γονιός είναι μικρότερος από τα παιδιά του (· · …) — αλλά τα αδέλφια δεν είναι ταξινομημένα μεταξύ τους, και δεν χρειάζεται.

Heapify-up — επιδιόρθωση προς τη ρίζα

Όταν εισάγουμε ένα στοιχείο, το βάζουμε στο τέλος του πίνακα — στην πρώτη ελεύθερη θέση, ώστε το σχήμα να μείνει ισοσταθμισμένο. Αλλά το κλειδί του μπορεί να είναι πολύ μικρό και να παραβιάζει την ιδιότητα — να είναι μικρότερο από τον γονέα του.

ΑλγόριθμοςHeapify-up — επιδιόρθωση προς τη ρίζα
O(log n)
Σπρώξε ένα πολύ μικρό στοιχείο προς τα πάνω, ανταλλάσσοντάς το με τον γονέα όσο είναι μικρότερό του.

Με λόγια. Το νέο, «ελαφρύ» στοιχείο αναδύεται σαν φυσαλίδα. Σε κάθε βήμα το συγκρίνουμε με τον γονέα του· αν είναι μικρότερο, τα ανταλλάσσουμε και συνεχίζουμε από τη νέα του θέση. Σταματάμε μόλις βρει γονέα μικρότερο από αυτό, ή φτάσει το ίδιο στη ρίζα.

Χρόνος. Το μονοπάτι προς τη ρίζα έχει μήκος , κάθε βήμα είναι . Η εισαγωγή (Insert) = «βάλε στο τέλος» + Heapify-up, δηλαδή κι αυτή .

Heapify-down — επιδιόρθωση προς τα φύλλα

Το συμμετρικό πρόβλημα: μια κορυφή έχει κλειδί πολύ μεγάλο — μεγαλύτερο από κάποιο παιδί της. Τη σπρώχνουμε προς τα κάτω.

ΑλγόριθμοςHeapify-down — επιδιόρθωση προς τα φύλλα
O(log n)
Σπρώξε ένα πολύ μεγάλο στοιχείο προς τα κάτω, ανταλλάσσοντάς το με το ΜΙΚΡΟΤΕΡΟ παιδί του.

Με λόγια. Συγκρίνουμε την κορυφή με τα παιδιά της. Αν κάποιο παιδί είναι μικρότερο, ανταλλάσσουμε με το μικρότερο από τα δύο και συνεχίζουμε προς τα κάτω. Σταματάμε όταν και τα δύο παιδιά είναι από αυτήν, ή όταν φτάσει σε φύλλο.

Χρόνος: ίδιο επιχείρημα — μονοπάτι προς τα φύλλα μήκους .

Δες και τις δύο επιδιορθώσεις να συμβαίνουν — εναλλάξου ανάμεσα στην Insert (που ανεβάζει) και στην ExtractMin (που κατεβάζει), και πρόσεξε πώς δέντρο και πίνακας κινούνται μαζί:

Σωρός βήμα-βήμα — δέντρο και πίνακας συγχρονισμένα
25891114182H[1]5H[2]8H[3]9H[4]11H[5]14H[6]18H[7]
Ένας έγκυρος σωρός 7 στοιχείων — κάθε γονέας ≤ τα παιδιά του. Θα εισάγουμε το 3.
Βήμα 0 / 5

Ουρά προτεραιότητας

Συνδυάζοντας τα παραπάνω παίρνουμε την ουρά προτεραιότητας — μια δομή που πάντα ξέρει «τι έχει σειρά»:

ΠράξηΤι κάνειΧρόνος
CreateHeap(H)κενός σωρός για στοιχεία
Insert(H, v)βάλε στο τέλος, Heapify-up
FindMin(H)επίστρεψε τη ρίζα
Delete(H, i)βγάλε τη θέση , Heapify-down (ή up)
ExtractMin(H)FindMin + διαγραφή της ρίζας

Η ουρά προτεραιότητας υποστηρίζει επίσης decreaseKey(H, v, k) — μειώνει το κλειδί ενός στοιχείου και καλεί Heapify-up. Αυτή ακριβώς είναι η πράξη που κάνουν ο Dijkstra και ο Prim όταν βρίσκουν φθηνότερο μονοπάτι ή ακμή προς μια κορυφή.

Δωρεάν μπόνους: Heapsort

Έχοντας την ουρά προτεραιότητας, ένας ολόκληρος αλγόριθμος ταξινόμησης μάς πέφτει στα χέρια χωρίς καμία νέα ιδέα. Σκέψου το: το ExtractMin επιστρέφει πάντα το τρέχον ελάχιστο. Αν το καλέσεις ξανά και ξανά, τα στοιχεία βγαίνουν από το μικρότερο προς το μεγαλύτερο — δηλαδή ταξινομημένα. Αυτός είναι όλος ο αλγόριθμος.

Ο Heapsort έχει λοιπόν δύο φάσεις:

  1. Χτίσιμο σωρού — βάλε και τα στοιχεία σε έναν σωρό. Με διαδοχικές Insert αυτό κοστίζει το πολύ .
  2. Άδειασμα — κάλεσε ExtractMin φορές. Κάθε κλήση , άρα συνολικά — και τα στοιχεία βγαίνουν σε αύξουσα σειρά.

Δες το να συμβαίνει: ο σωρός πρώτα γεμίζει, μετά στραγγίζει στοιχείο-στοιχείο σε μια ταξινομημένη έξοδο.

Heapsort — ο σωρός γεμίζει, μετά αδειάζει ταξινομημένος
Έτοιμοι
(ο σωρός είναι άδειος)
Ταξινομημένη έξοδος
·
·
·
·
·
·
Δίνονται 6 αριθμοί: 7, 2, 9, 4, 11, 5. Το Heapsort τους ταξινομεί σε δύο φάσεις — πρώτα χτίζει έναν σωρό, μετά τον αδειάζει.
Βήμα 0 / 12

Χρόνος: — το ίδιο φράγμα με τη συγχωνευτική ταξινόμηση του L03, αλλά από εντελώς διαφορετικό δρόμο: εκεί «διαίρει και κυρίευε», εδώ «μια δομή που ξέρει πάντα πού είναι το ελάχιστο».

Πώς ο σωρός επιταχύνει τον Dijkstra και τον Prim

Τώρα κλείνει η πρώτη υπόσχεση του L09. Και οι δύο αλγόριθμοι κρατούν μια ουρά προτεραιότητας από ανεξερεύνητες κορυφές:

  • ExtractMin — διάλεξε την επόμενη κορυφή. Καλείται φορές → .
  • decreaseKey — όταν μια κορυφή μπει στο , ενημέρωσε τις προτεραιότητες των γειτόνων της. Συνολικά μέχρι φορές → .

Σύνολο — ακριβώς το φράγμα του L09. Χωρίς σωρό, το ExtractMin θα ήταν γραμμική σάρωση και θα κατέληγες σε .

Κάρτα μνήμηςΣωρός (Heap)
Λέξεις-κλειδιά
ισοσταθμισμένο δυαδικό δέντρογονέας ≤ παιδιάπίνακας: γονέας ⌊i/2⌋heapify-up / heapify-downρίζα = ελάχιστο
Τα βήματα στο μυαλό σου
1Σχήμα: ισοσταθμισμένο δυαδικό δέντρο — ύψος ⌊log₂ n⌋.
2Διάταξη: κάθε γονέας ≤ κάθε παιδί του, άρα η ρίζα κρατά το ελάχιστο.
3Insert: βάλε στο τέλος, heapify-up (ανέβασέ το όσο είναι < γονέας).
4ExtractMin: επίστρεψε τη ρίζα, φέρε το τελευταίο πάνω, heapify-down (κατέβασέ το προς το μικρότερο παιδί).
Πολυπλοκότητα
FindMin O(1) · Insert/ExtractMin O(log n)
Κλασική παγίδα
Στο heapify-down ανταλλάσσεις πάντα με το ΜΙΚΡΟΤΕΡΟ από τα δύο παιδιά — με το μεγαλύτερο, η ιδιότητα παραβιάζεται ξανά αμέσως. Και ο σωρός δεν λέει τίποτα για αδέλφια: είναι μόνο «χαλαρά» ταξινομημένος, όχι πλήρως.

Μέρος Β' — Ξένα Σύνολα (Union-Find)

Το πρόβλημα που λύνουν

Θυμήσου τον Kruskal από το L09: σαρώνει ακμές σε αύξουσα σειρά κόστους και προσθέτει την εκτός αν δημιουργεί κύκλο. Πότε δημιουργεί κύκλο; Ακριβώς όταν οι και είναι ήδη στην ίδια συνεκτική συνιστώσα του μέχρι τώρα δέντρου.

Χρειαζόμαστε λοιπόν μια δομή που κρατά μια διαμέριση — μια συλλογή από ανά δύο ξένα σύνολα — και απαντά γρήγορα: «το και το είναι στο ίδιο σύνολο;»

Εφαρμογή — συνεκτικές συνιστώσες

Με αυτές τις τρεις πράξεις, η εύρεση των συνεκτικών συνιστωσών ενός γραφήματος γίνεται μηχανική.

ΑλγόριθμοςΣυνεκτικές συνιστώσες με union-find
O((n + m) · α(n))
Κάθε κορυφή ξεκινά μόνη της· κάθε ακμή «κολλάει» τα δύο της άκρα στην ίδια συνιστώσα.
Είσοδος:
γράφημα G = (V, E)
Έξοδος:
μια διαμέριση των κορυφών στις συνεκτικές συνιστώσες

Με λόγια. Φτιάξε ένα ξεχωριστό σύνολο για κάθε κορυφή. Μετά, για κάθε ακμή, ένωσε τα σύνολα των δύο άκρων της (αν είναι ήδη μαζί, δεν χρειάζεται). Στο τέλος, δύο κορυφές είναι στην ίδια συνιστώσα ακριβώς όταν έχουν τον ίδιο Find.

Μια αφελής προσέγγιση — και γιατί δεν φτάνει

Η πιο απλή ιδέα: ένας πίνακας , όπου είναι το «όνομα» του συνόλου του .

  • Find(x) — επίστρεψε . — εξαιρετικό.
  • Union(x, y) — διάλεξε ένα όνομα και σάρωσε όλον τον πίνακα αλλάζοντας κάθε εμφάνιση του άλλου ονόματος. — απαίσιο.

Με ενώσεις φτάνουμε . Πληρώνουμε υπερβολικά στο Union. Χρειαζόμαστε καλύτερη ισορροπία.

Κάθε σύνολο ένα δέντρο με ρίζα

Η σωστή ιδέα: αναπαριστούμε κάθε σύνολο σαν ένα κατευθυνόμενο δέντρο με ρίζα.

  • Κάθε κορυφή έχει έναν δείκτη — προς τον γονέα της.
  • Η ρίζα δείχνει στον εαυτό της και είναι ο αντιπρόσωπος του συνόλου.
  • Πολλά ξένα σύνολα → ένα κατευθυνόμενο δάσος.

Με αυτή την αναπαράσταση, οι τρεις πράξεις γίνονται απλές:

  • MakeSet(x) — ένα δέντρο με μία μόνο κορυφή, που δείχνει στον εαυτό της. .
  • Find(x) — ακολούθησε τους δείκτες-γονείς από το προς τα πάνω, ως τη ρίζα· επίστρεψέ την.
  • Union(x, y) — βρες τις δύο ρίζες, και κάνε τη μία να δείχνει στην άλλη. αφού έχεις τις ρίζες.

Τρέξε μια ακολουθία από αυτές τις πράξεις και δες το δάσος να σχηματίζεται. Πρόσεξε δύο πράγματα: το Find ανεβαίνει πάντα μέχρι τη ρίζα, και ο πίνακας γονέων από κάτω είναι το ίδιο ακριβώς δάσος, γραμμένο σαν απλοί αριθμοί.

Union-Find — κάθε σύνολο ένα δέντρο με ρίζα
MakeSet ×7

Ίδιο χρώμα = ίδιο σύνολο · βέλος = δείκτης προς τον γονέα · 7 σύνολα τώρα

1234567
Πίνακας γονέων — parent[ ]
11ρίζα
22ρίζα
33ρίζα
44ρίζα
55ρίζα
66ρίζα
77ρίζα
Επτά στοιχεία, επτά ξεχωριστά σύνολα. Το MakeSet δίνει στο καθένα το δικό του δέντρο μιας κορυφής — ρίζα του εαυτού του.
Βήμα 0 / 8

Πρώτη βελτίωση: union by size

Η προειδοποίηση πιο πάνω είπε ότι ο εχθρός είναι η αλυσίδα. Να ο φθηνός τρόπος να την αποφεύγουμε: για κάθε δέντρο αποθηκεύουμε το μέγεθός του, και στο Union κάνουμε πάντα τη ρίζα του μικρότερου δέντρου να δείχνει στη ρίζα του μεγαλύτερου — ποτέ ανάποδα.

Το παρακάτω εργαλείο τρέχει την ίδια ακολουθία ενώσεων με δύο στρατηγικές. Πάνω, η απλοϊκή ένωση που αγνοεί τα μεγέθη· κάτω, το union by size. Δες το βάθος του ενός να εκτοξεύεται και του άλλου να μένει καρφωμένο:

Union by size — η ίδια ακολουθία, δύο στρατηγικές
Αρχή
Απλοϊκή ένωση
βάθος: 0 · χειρότερο Find 0 βήματα
Union by size
βάθος: 0 · χειρότερο Find 0 βήματα
Απλοϊκή ένωση — αγνοεί τα μεγέθη12345Union by size — μικρό κάτω από μεγάλο12345
Πέντε μεμονωμένα στοιχεία — και οι δύο πλευρές ξεκινούν ίδιες. Θα τρέξουμε ΤΗΝ ΙΔΙΑ ακολουθία ενώσεων· η μόνη διαφορά είναι ποιο δέντρο κρεμιέται κάτω από ποιο.
Βήμα 0 / 4

Η εικόνα γίνεται θεώρημα:

Δεύτερη βελτίωση: συμπίεση μονοπατιών

Σχεδόν δωρεάν — και κρύβεται μέσα σε μια πράξη που κάνουμε ήδη. Κάθε φορά που τρέχουμε Find(v), διασχίζουμε ολόκληρο το μονοπάτι από το ως τη ρίζα· το πληρώσαμε ήδη. Πριν επιστρέψουμε, λοιπόν, ξανασυνδέουμε κάθε κορυφή αυτού του μονοπατιού απευθείας στη ρίζα.

Δες το να συμβαίνει: μια Find σε ένα σχεδόν εκφυλισμένο δέντρο πληρώνει τη μακριά διαδρομή μία φορά — και την ισιώνει στο πέρασμά της, ώστε η επόμενη να είναι ακαριαία.

Συμπίεση μονοπατιού — πλήρωσε μία φορά, κέρδισε για πάντα
Αρχή

Αναπηδήσεις αυτής της Find: 0

1234567
Πίνακας γονέων — parent[ ]
11ρίζα
21γονέας
32γονέας
43γονέας
54γονέας
65γονέας
74γονέας
Αυτό το δέντρο union-find έχει εκφυλιστεί σχεδόν σε αλυσίδα. Θα τρέξουμε Find(6) — και θα δούμε τη συμπίεση μονοπατιού να το ισιώνει.
Βήμα 0 / 8

Με union by size + συμπίεση μονοπατιών μαζί συμβαίνει κάτι σχεδόν μαγικό: μια ακολουθία πράξεων σε στοιχεία τρέχει σε .

Πώς το union-find επιταχύνει τον Kruskal

Κλείνει και η δεύτερη υπόσχεση του L09. Στον Kruskal, ο έλεγχος «κλείνει κύκλο;» γίνεται με ένα ζεύγος Find, και η προσθήκη ακμής με ένα Union:

  • Ταξινόμηση: .
  • ζεύγη Find + έως Union: — ουσιαστικά γραμμικό.
  • Σύνολο: — η ταξινόμηση κυριαρχεί. Ακριβώς το φράγμα του L09.
Κάρτα μνήμηςUnion-Find (ξένα σύνολα)
Λέξεις-κλειδιά
κάθε σύνολο = δέντρο με ρίζαFind = ανέβα ως τη ρίζαunion by sizeσυμπίεση μονοπατιώνO(α(n)) ανά πράξη
Τα βήματα στο μυαλό σου
1MakeSet: κάθε στοιχείο μόνο του, δείκτης στον εαυτό του.
2Find(x): ακολούθησε τους δείκτες-γονείς ως τη ρίζα — αυτή είναι ο αντιπρόσωπος.
3Union(x, y): βρες τις δύο ρίζες, κρέμασε τη μικρότερη κάτω από τη μεγαλύτερη.
4Συμπίεση μονοπατιών: μετά από Find, ξανασύνδεσε όλο το μονοπάτι απευθείας στη ρίζα.
Πολυπλοκότητα
O(α(n)) αμορτοποιημένα — πρακτικά σταθερό
Κλασική παγίδα
Χωρίς union by size τα δέντρα εκφυλίζονται σε αλυσίδες και το Find γίνεται O(n). «Ίδιο σύνολο;» σημαίνει ίδιο Find — όχι σύγκριση δεικτών-γονέων· δύο στοιχεία είναι μαζί ανν Find(x) = Find(y).

Κλείδωσε τη γνώση

Βάλε στη σειρά τα βήματα του ExtractMin:

Βάλε τα βήματα στη σειρά
Η πράξη ExtractMin ενός σωρού, από την πρώτη ενέργεια στην τελευταία.
Σύρε τις γραμμές για αναδιάταξη — ή χρησιμοποίησε τα βελάκια.
1.Επίστρεψε το αποθηκευμένο ελάχιστο.
2.Σύγκρινε το νέο στοιχείο της ρίζας με το μικρότερο από τα παιδιά του.
3.Μείωσε το μέγεθος του σωρού κατά ένα.
4.Φέρε το τελευταίο στοιχείο του σωρού στη θέση της ρίζας.
5.Όσο κάποιο παιδί είναι μικρότερο, αντάλλαξέ τα και κατέβα — heapify-down.
6.Διάβασε τη ρίζα H[1] — αυτό είναι το ελάχιστο που θα επιστραφεί· κράτησέ το.

Και συμπλήρωσε τα κενά για το union-find:

Συμπλήρωσε τα κενά
Η δομή ξένων συνόλων σε τέσσερις λέξεις-κλειδιά.
Στο union-find, κάθε σύνολο αναπαρίσταται ως ένα δέντρο με , που είναι ο αντιπρόσωπός του. Η πράξη Find ανεβαίνει ως εκεί, οπότε δύο στοιχεία ανήκουν στο ίδιο σύνολο αν έχουν το ίδιο . Η τεχνική union by size κρεμάει το δέντρο κάτω από το μεγαλύτερο, κρατώντας το βάθος O(log n) — και η συμπίεση μονοπατιών το μικραίνει κι άλλο, ώστε κάθε πράξη να κοστίζει πρακτικά χρόνο.

Μοτίβο σκέψης

Τι μάθαμε

Τι κρατάμε από αυτή τη διάλεξη

  1. Σωρός — ισοσταθμισμένο δυαδικό δέντρο με ιδιότητα διάταξης (γονιός παιδιά). Αποθηκεύεται σε πίνακα: , παιδιά και — μηδέν δείκτες.
  2. Heapify-up / Heapify-down — επιδιορθώνουν μία παραβίαση σε , σπρώχνοντας ένα στοιχείο προς τη ρίζα ή προς τα φύλλα (πάντα προς το μικρότερο παιδί).
  3. Ουρά προτεραιότηταςFindMin , Insert/ExtractMin . Δίνει Heapsort και κάνει Dijkstra & Prim .
  4. Union-FindMakeSet, Union, Find πάνω σε διαμέριση σε ξένα σύνολα. Κάθε σύνολο = δέντρο με ρίζα = αντιπρόσωπο.
  5. Union by size κρατά το βάθος · η συμπίεση μονοπατιών το μικραίνει κι άλλο. Μαζί → ανά πράξη, πρακτικά σταθερό.
  6. Το union-find κάνει τον Kruskal — η ταξινόμηση των ακμών είναι πια το ακριβό κομμάτι.
Επόμενο
L11 · Άπληστοι I — interval scheduling, exchange argument

Ασκήσεις από εξετάσεις

Από τη θεωρία στην εξεταστική

3 άσκησεις που χρησιμοποιούν ως τελευταίο εργαλείο αυτή τη διάλεξη. Οι πρόσφατες εξεταστικές (2024/2025) φέρουν badge προτεραιότητας.

Από φροντιστήριοΦροντιστήριο 2023–24Άσκηση 10Δομές δεδομένωνΔύσκολο

Φροντιστηριακό Σετ #5 · Άσκηση 10 — Πυθαγόρεια τετράδα σε O(n²)

Μια Πυθαγόρεια τετράδα είναι ακέραιοι με , δηλαδή . Σχεδίασε αλγόριθμο που αποφασίζει αν υπάρχει Πυθαγόρεια τετράδα σε έναν πίνακα διακριτών θετικών ακεραίων (επιτρέπεται η πολλαπλή χρήση ενός στοιχείου).

Από φροντιστήριοΦροντιστήριο 2023–24Άσκηση 11Δομές δεδομένωνΜέτριο

Φροντιστηριακό Σετ #5 · Άσκηση 11 — Ζεύγη με δοσμένο άθροισμα σε O(n)

Σχεδίασε αλγόριθμο που, δοθέντος ενός πίνακα με διαφορετικούς ακεραίους στο εύρος και τιμή στόχο , εκτυπώνει όλα τα ζεύγη με . Ο αναμενόμενος χρόνος πρέπει να είναι .

Παλαιό θέμαΣεπτέμβριος 2023Θέμα 325%Δομές δεδομένωνΜέτριο

Σεπτέμβριος 2023 · Θέμα 3 — Master Theorem & επιδιόρθωση σωρού

(Α) Να επιλυθεί η αναδρομική εξίσωση , όπου και μια σταθερά θετική, με χρήση του Θεωρήματος Κυριαρχίας (Master Theorem).

(Β) Η ακολουθία είναι αποθηκευμένη στον μονοδιάστατο πίνακα υπό δομή σωρού (max-heap). Κάποιος όρος αλλάζει και παίρνει μικρότερη τιμή. Ο νέος πίνακας ενδέχεται να μην είναι πλέον σωρός.

i. Να δοθεί σύντομα ένας αναδρομικός αλγόριθμος που διατηρεί στον τη δομή σωρού. ii. Να δοθεί η αναδρομική σχέση που περιγράφει την πολυπλοκότητα του αλγορίθμου στη χείριστη περίπτωση. iii. Να επιλυθεί η , με . iv. Εφαρμόστε τον αλγόριθμο για έναν εσωτερικό κόμβο που κρατούσε την τιμή , όταν αυτή αλλάζει σε και όταν αλλάζει σε (τα παιδιά του κόμβου κρατούν τις τιμές και ).

Φόρτωση σχολίων…
L10 · Δομές Δεδομένων — Σωροί & Ξένα Σύνολα · Algorithms Class Hub