Πολλαπλασιασμός δισδιάστατων πινάκων

Σχετικά έγγραφα
Δζντρα. Δομζσ Δεδομζνων

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

Δομζσ Δεδομζνων. Αναηιτθςθ και Ταξινόμθςθ Διάλεξθ 3

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

Δομζσ Δεδομζνων Πίνακεσ

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

Πληροφορική 2. Αλγόριθμοι

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

3 ΟΥ και 9 ΟΥ ΚΕΦΑΛΑΙΟΥ

ΣΧΟΛΗ ΔΙΟΙΚΗΣΗΣ ΚΑΙ ΟΙΚΟΝΟΜΙΑΣ ΤΜΗΜΑ ΔΙΟΙΚΗΣΗΣ ΕΠΙΧΕΙΡΗΣΕΩΝ (ΠΑΤΡΑ) ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ

ιαφάνειες παρουσίασης #11

ΒΑΣΙΚΕΣ ΕΠΕΞΕΡΓΑΣΙΕΣ ΜΟΝΟΔΙΑΣΤΑΤΩΝ ΚΑΙ ΔΙΣΔΙΑΣΤΑΤΩΝ ΠΙΝΑΚΩΝ ΟΙ ΠΙΟ ΣΗΜΑΝΤΙΚΟΙ ΑΛΓΟΡΙΘΜΟΙ

Αλγόριθμοι και Δομές Δεδομένων (IΙ) (γράφοι και δένδρα)

Οι βασικές λειτουργίες (ή πράξεις) που γίνονται σε μια δομή δεδομένων είναι:

ΣΗΜΕΙΩΣΕΙΣ ΘΕΩΡΙΑΣ ΚΕΦΑΛΑΙΟ 3 ΠΡΟΣΘΗΚΗ

Κάθε στοιχείο που γίνεται αντιληπτό με μία από τις πέντε αισθήσεις μας

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

Ιςοηυγιςμζνα δζντρα και Β- δζντρα. Δομζσ Δεδομζνων

Ερωτήσεις πολλαπλής επιλογής - Κεφάλαιο Κάθε δομή μπορεί να χρησιμοποιηθεί σε οποιοδήποτε πρόβλημα ή εφαρμογή

ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ & ΑΛΓΟΡΙΘΜΟΙ. Πίνακες και βασικές επεξεργασίες αυτών

Οι δομές δεδομένων στοίβα και ουρά

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΠΛΗΡΟΦΟΡΙΚΗ

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

Ενότητα 3: ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΚΑΙ ΑΛΓΟΡΙΘΜΟΙ

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

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

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

Διδάσκων: Κωνσταντίνος Κώστα

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

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

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΣΧΟΛΙΚΟΥ ΕΤΟΥΣ

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

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΠΡΟΣΟΜΟΙΩΣΗΣ ΠΑΝΕΛΛΑΔΙΚΩΝ ΣΧΟΛΙΚΟΥ ΕΤΟΥΣ

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

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

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ Κεφάλαιο 3 ο

Επιµέλεια Θοδωρής Πιερράτος

ΘΕΜΑΤΑ ΠΡΟΣΟΜΟΙΩΣΗΣ ΠΑΝΕΛΛΑΔΙΚΩΝ ΕΞΕΤΑΣΕΩΝ Γ ΤΑΞΗΣ ΗΜΕΡΗΣΙΟΥ ΓΕΝΙΚΟΥ ΛΥΚΕΙΟΥ ΕΞΕΤΑΖΟΜΕΝΟ ΜΑΘΗΜΑ: ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΠΡΟΣΟΜΟΙΩΣΗΣ ΠΑΝΕΛΛΑΔΙΚΩΝ ΣΧΟΛΙΚΟΥ ΕΤΟΥΣ

ΚΕΦΑΛΑΙΟ 3 ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΚΑΙ ΑΛΓΟΡΙΘΜΟΙ

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

Ελληνική Δημοκρατία Τεχνολογικό Εκπαιδευτικό Ίδρυμα Ηπείρου. Πληροφορική II. Ενότητα 2 : Αλγόριθμοι. Δρ. Γκόγκος Χρήστος

Πίνακες. Ι.Ε.Κ ΓΛΥΦΑΔΑΣ Τεχνικός Τεχνολογίας Internet Αλγοριθμική Ι (Ε) Σχολ. Ετος A Εξάμηνο

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

I. ΑΛΓΟΡΙΘΜΟΣ II. ΠΡΑΞΕΙΣ - ΣΥΝΑΡΤΗΣΕΙΣ III. ΕΠΑΝΑΛΗΨΕΙΣ. 1. Τα πιο συνηθισμένα σενάρια παραβίασης αλγοριθμικών κριτηρίων είναι:

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

σας φύλλο τον αριθμό της ερώτησης ακολουθούμενη από το γράμμα Σ (Σωστή) ή το γράμμα Λ (Λάθος).

2.2.5 ΑΝΑΠΑΡΑΣΤΑΣΗ ΑΛΓΟΡΙΘΜΟΥ

Βασικές δοµές δεδοµένων. Ορολογία λιστών. 8.1 Βασικές έννοιες δοµών δεδοµένων 8.2 Υλοποίηση δοµών δεδοµένων 8.3 Μια σύντοµη υπόθεση εργασίας

Οντοκεντρικός Προγραμματισμός

ΕΞΕΤΑΖΟΜΕΝΟ ΜΑΘΗΜΑ : ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΤΑΞΗ : Γ ΛΥΚΕΙΟΥ ΣΠΟΥΔΕΣ ΟΙΚΟΝΟΜΙΑΣ & ΠΛΗΡΟΦΟΡΙΚΗΣ

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

Διορθώσεις σελ

Ερωτήσεις πολλαπλής επιλογής - Κεφάλαιο 2

ΚΕΦΑΛΑΙΟ 8: Αφαίρεση δεδοµένων

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

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

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

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

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

Γ7.5 Αλγόριθμοι Αναζήτησης. Γ Λυκείου Κατεύθυνσης

Προγραμματιστικές Τεχνικές

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

ΘΕΜΑ Α ΑΡΧΗ 1ΗΣ ΣΕΛΙΔΑΣ

Φίλη μαθήτρια, φίλε μαθητή,

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 10 Δυαδικά Δένδρα Αναζήτησης

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ. 1 ο ΚΕΦΑΛΑΙΟ

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

ΠΡΟΣ: Τηλέφωνο: Ινστιτούτο Εκπαιδευτικής Πολιτικής ΚΟΙΝ.:

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

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

Έστω ένας πίνακας με όνομα Α δέκα θέσεων : 1 η 2 η 3 η 4 η 5 η 6 η 7 η 8 η 9 η 10 η

Α2. Να αναφέρετε ονομαστικά τις βασικές λειτουργίες που εκτελεί ένας υπολογιστής (Μονάδες 3)

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΕΠΑΝΑΛΗΠΤΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΟΝΟΜΑΤΕΠΩΝΥΜΟ:

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

Προγραμματισμός Η/Υ (ΤΛ2007 )

Εργαστηριακή Άσκηση 1

ΔΙΑΓΩΝΙΣΜΑ ΣΤΗΝ Α.Ε.Π.Π. Γ ΤΕΧΝΟΛΟΓΙΚΗΣ. Όνομα:.. Βαθμός: /100

Αλγόριθμοι και Δομές Δεδομένων (Ι) (εισαγωγικές έννοιες)

ΑΕΠΠ - ΗΜΕΡΗΣΙΑ ΛΥΚΕΙΑ ΘΕΜΑΤΑ ΚΑΙ ΛΥΣΕΙΣ

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

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

Διαδικασιακός Προγραμματισμός

Επιλέξτε Σωστό ή Λάθος για καθένα από τα παρακάτω:

Σύνοψη Προηγούμενου. Πίνακες (Arrays) Πίνακες (Arrays): Βασικές Λειτουργίες. Πίνακες (Arrays) Ορέστης Τελέλης

Ενδεικτικές Ερωτήσεις Θεωρίας

Αν ένα πρόβλημα λύνεται από δύο ή περισσότερους αλγόριθμους, ποιος θα είναι ο καλύτερος; Με ποια κριτήρια θα τους συγκρίνουμε;

Αλγόριθμοι και δομές δεδομένων

Πληροφορική 2. Δομές δεδομένων και αρχείων

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

Σε μια στοίβα 10 θέσεων έχουν τοποθετηθεί διαδοχικά τα στοιχεία: Σ, Γ, Μ, Α, Δ στην 1η, 2η, 3η, 4η και 5η θέση αντίστοιχα. Να προσδιορίσετε την τιμή

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

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

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

Τι είναι αλγόριθμος; Υποπρογράμματα (υποαλγόριθμοι) Βασικές αλγοριθμικές δομές

Ακρότατα πίνακα, χωρίς min, max, μόνο με pos

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

Δένδρα. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα:

ΕΚΠΑΙΔΕΥΤΗΡΙΑ ΝΕΑ ΠΑΙΔΕΙΑ

ΕΞΕΤΑΖΟΜΕΝΟ ΜΑΘΗΜΑ : ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ ΤΑΞΗ : Γ ΛΥΚΕΙΟΥ ΣΠΟΥΔΕΣ ΟΙΚΟΝΟΜΙΑΣ & ΠΛΗΡΟΦΟΡΙΚΗΣ

Transcript:

Δομές δεδομένων 1 η εργαστηριακή άσκηση Ο πίνακας αποτελεί την πιο απλή δομή δεδομένων και αποτελείται από ένα σύνολο απλών ομοειδών στοιχείων (ακέραιοι, χαρακτήρες κτλ). Το μέγεθος ενός πίνακα είναι σταθερό και προκαθορισμένο, ενώ η αναφορά σε ένα στοιχείο του πίνακα γίνεται με τη χρήση ενός ονόματος του πίνακα καθώς και με ένα σύνολο στοιχείων που ονομάζονται δείκτες (indexes) πχ A[i] ή Α i. Οι δισδιάστατοι πίνακες και μονοδιάστατοι πίνακες (διανύσματα) χρησιμοποιούνται ευρέως για την δημιουργία λογισμικού που αφορά την επίλυση επιστημονικών προβλημάτων. Οι πίνακες αυτοί περιέχουν στα στοιχεία τους αριθμούς είτε ακέραιους είτε πραγματικούς. Στην παρούσα άσκηση θα εξετάσουμε δύο λειτουργίες που μπορούμε να κάνουμε πάνω σε αυτήν την δομή. Η πρώτη λειτουργία αφορά των πολλαπλασιασμό πινάκων (δημιουργία, τροποποίηση των στοιχείων ενός πίνακα) και η δεύτερη αφορά την αναζήτηση ενός στοιχείου σε έναν πίνακα. Πολλαπλασιασμός δισδιάστατων πινάκων Έστω οι έχουμε τους πίνακες Α και Β, με διαστάσεις mxn και kxr. Για να γίνει η πράξη του πολλαπλασιαμού C=ΑΒ θα πρέπει να ισχύει n=k, ενώ η διάσταση του πίνακα C θα είναι mxr. Αντίστοιχα, για να γίνει η πράξη του πολλαπλασιασμού C = ΒΑ θα πρέπει να ισχύει r=m και η διάσταση του C θα είναι kxm. (Ερώτηση: Τι είναι η διάσταση ενός πίνακα;) Σύμφωνα με τα παραπάνω ο πολλαπλασιασμός δυο πινάκων ορίζεται μόνο όταν οι στήλες του πρώτου ισούνται με τις γραμμές του δεύτερου. Ο πολλαπλασιασμός του n m πινάκα A= με τον m k B= έχει ως αποτέλεσμα τον n k πίνακα C=AB= με στοιχεία Στην παρακάτω εικόνα βλέπουμε μια σχηματική αναπαράσταση του πολλαπλασιασμού μεταξύ δύο πινάκων.

Παράδειγμα: έστω ότι έχουμε του πίνακες Α = 1 2 5 2 1 1 3 12 και Β = 3 7 4 6 Τότε ο πίνακας C = AB προκύπτει ως εξής: C = 1 2 + 2 3 + 5 4 1 1 + 2 7 + 5 6 1 2 + 3 3 + 12 4 1 1 + 3 7 + 12 6 = 2 + 6 + 20 1 + 14 + 30 2 + 9 + 48 1 + 21 + 72 = 28 45 59 94 (Ερώτησεις: 1. Ποιός θα ήταν ο πίνακας C = BA; 2. Τι μπορούμε να πούμε για τους μονοδιάστατους πίνακες διανύσματα;) Παρακάτω δίνεται ο αλγόριθμος πολλαπλασιασμού 2 δισδιάστατων πινάκων σε ψευδογλώσσα. Σκοπός σας είναι να γράψετε τον αλγόριθμο σε C++. Αλγόριθμος MultiplyMatrices Δεδομένα // a[][],b[][],m,n,r // /*Αρχικοποίηση του πίνακα C*/ Για i από 1 μέχρι M με_βήμα 1 Για k από 1 μέχρι N με_βήμα 1 c[i][k] = 0 Τέλος_επανάληψης Τέλος_επανάληψης

/* Υπολογισμός του πολ/σμού πινάκων: C=AB */ Για i από 1 μέχρι M με_βήμα 1 Για k από 1 μέχρι N με_βήμα 1 Για r από 1 μέχρι R με_βήμα 1 c[i][k] = c[i][k] + a[i][r]*b[r][k] Τέλος_επανάληψης Τέλος_επανάληψης Τέλος_επανάληψης /* Εκτύπωση στοιχείων του πίνακα C*/ Για i από 1 μέχρι M με_βήμα 1 Για k από 1 μέχρι N με_βήμα 1 Εκτύπωσε c[i][k] + ' ' Τέλος_επανάληψης Εκτύπωσε '\n' Τέλος_επανάληψης Τέλος MultiplyMatrices ΣΗΜΕΙΩΣΗ: Στον παραπάνω αλγόριθμο θεωρούνται γνωστά οι πίνακες Α και Β, καθώς και η διάσταση του κάθε πίνακα. Στο πρόγραμμα που θα γράψετε σε C++ αυτά τα δεδομένα θα πρέπει να καθοριστούν. Δυαδική αναζήτηση Η σειριακή αναζητηση είναι η πιο απλή και άμεση μέθοδος αναζήτησης. Ο αλγόριθμος εξετάζει διαδοχικά τα στοιχεία του πίνακα μέχρι να βρεί το ζητούμενο. Παρακάτω περιγράφεται ο αλγόριθμος Sequential-Search σε ψευδογλώσσα, σκοπός είναι να γράψετε αυτόν τον αλγόριθμο σε C++. Στον αλγόριθμο αυτό τα δεδομένα είναι: ο πίνακας Ε, στον οποίο αναζητείται ένα στοιχείο, το μέγεθος του πίνακα Ν και K το στοιχείο προς αναζήτηση Αλγόριθμος Sequential-Search Δεδομένα // Ε[],N,K // i=1, ex=false, index=0 Όσο i N επανάλαβε Αν K == Ε[i] τότε index = i i = N+1 ex = true

αλλιώς i = i+1 Τέλος_αν Τέλος_επανάληψης Αποτελέσματα // ex,index// Τέλος Sequential - Search

Δυαδική αναζήτηση Δομές Δεδομένων 2 η εργαστηριακή άσκηση - Αναζήτηση και Ταξινόμηση Στην παρακάτω άσκηση θα εξετάσουμε τον αλγόριθμο αναζήτησης που καλείται δυαδική αναζήτηση. Δυαδική αναζήτηση ονομάζεται ένας αναδρομικός αλγόριθμος αναζήτησης ενός στοιχείου (το λεγόμενο στοιχείο-κλειδί) σε έναν ταξινομημένο μονοδιάστατο πίνακα. Ο αλγόριθμος αυτός χρησιμοποιεί την τεχνική Διαίρει και Βασίλευε. Εν γένει, η αναζήτηση σε έναν μη ταξινομημένο πίνακα γίνεται σε χρόνο γραμμικό ως προς το μέγεθος της εισόδου, συγκρίνοντας ένα προς ένα τα στοιχεία της εισόδου με το κλειδί. Όμως, η δυαδική αναζήτηση στηρίζεται στο γεγονός ότι ο πίνακας είναι ταξινομημένος, μειώνοντας έτσι σημαντικά τον αριθμό των συγκρίσεων που απαιτούνται. Εναλλακτικά μπορεί να χρησιμοποιηθεί κάποια άλλη δομή δεδομένων, αλλά είναι απαραίτητο αυτή να υποστηρίζει την τυχαία προσπέλαση σε σταθερό χρόνο, ώστε να διατηρηθεί η λογαριθμική ταχύτητα του αλγορίθμου. Για παράδειγμα, η δυαδική αναζήτηση δεν μπορεί να εφαρμοστεί σε μια δομή δεδομένων όπως η λίστα. Περιγραφή Ο αλγόριθμος δέχεται ως είσοδο έναν ταξινομημένο μονοδιάστατο πίνακα (διάνυσμα) και μια τιμή που ονομάζεται κλειδί (key). Επιστρέφει την θέση του κλειδιού στο διάνυσμα ή μια ειδική ένδειξη για να ενημερώσει ότι το κλειδί δεν υπάρχει στο διάνυσμα, αν αυτή είναι η περίπτωση. Το διάνυσμα μπορεί να είναι ταξινομημένο είτε σε αύξουσα σειρά είτε σε φθίνουσα, αλλά και στις δύο περιπτώσεις ο αλγόριθμος λειτουργεί σωστά (με τις κατάλληλες τροποποιήσεις) και καταναλώνει τον ίδιο χρόνο. Λόγω της ισοδυναμίας αυτής, μπορούμε χωρίς βλάβη της γενικότητας, να θεωρήσουμε ότι το διάνυσμα είναι ταξινομημένο κατά αύξουσα σειρά. Επειδή το διάνυσμα είναι σε αύξουσα σειρά, η τιμή του στοιχείου στη θέση i του διανύσματος θα είναι μικρότερη ή ίση από όλα τα στοιχεία δεξιά και μεγαλύτερη ή ίση από όλα τα στοιχεία αριστερά (η ισότητα μπορεί να προκύψει μόνο στην περίπτωση που υπάρχουν επαναλαμβανόμενες τιμές). Έτσι, αν σε μια σύγκριση, το κλειδί είναι μεγαλύτερο από το στοιχείο στη θέση i, δεν έχει νόημα να κάνουμε συγκρίσεις με τα στοιχεία που βρίσκονται σε θέση j<i (δηλαδή, αριστερά από τη θέση i). Αυτήν ακριβώς την ιδιότητα εκμεταλλεύεται η δυαδική αναζήτηση, ώστε να μειώσει κατά το δυνατό τις συγκρίσεις που κάνει. Αρχικά, το εύρος των θέσεων στις οποίες μπορεί να βρίσκεται το στοιχείο με τιμή ίση με το κλειδί είναι το μεγαλύτερο δυνατό. Δηλαδή, αρχικά ο αλγόριθμος θεωρεί ότι το κλειδί μπορεί να βρίσκεται οπουδήποτε μέσα στο διάνυσμα. 1. Ξεκινά συγκρίνοντας το κλειδί με την τιμή του στοιχείου που βρίσκεται στο μέσο του διανύσματος. 2. Αν είναι ίσα, τότε ο αλγόριθμος τερματίζει επιστρέφοντας τη θέση αυτή.

3. Αν το κλειδί είναι μεγαλύτερο, τότε μειώνει το εύρος στο δεξί-μισό τμήμα του προηγούμενου τμήματος που εξέταζε και επαναλαμβάνει το πρώτο βήμα όχι για όλο το διάνυσμα, αλλά μόνο για το τμήμα του διανύσματος που επέλεξε. 4. Αν το κλειδί είναι μικρότερο, τότε μειώνει το εύρος στο αριστερό-μισό τμήμα του προηγούμενου τμήματος που εξέταζε και επαναλαμβάνει το πρώτο βήμα όχι για όλο το διάνυσμα, αλλά μόνο για το τμήμα του διανύσματος που επέλεξε. Μετά από έναν πεπερασμένο αριθμό βημάτων, ο αλγόριθμος είτε θα βρει τη ζητούμενη θέση, είτε θα μειώσει το εύρος της αναζήτησης στο μηδέν, που σημαίνει ότι το κλειδί δεν βρέθηκε στο διάνυσμα, και θα επιστρέψει την αντίστοιχη ένδειξη. Παρακάτω δίνεται ο ψευδοκώδικας όπου περιγράφεται η δυαδική αναζήτηση. Να γραφεί πρόγραμμα όπου θα υλοποιεί σε C++ τον παρακάτω αλγόριθμο. Επίσης να δοκιμάσετε τον αλγόριθμο στον πίνακα Κ=1,2,5,6,8,44,67,89,99,789 για διάφορες τμές του κλειδιού (key) που θα δίνονται από το πληκτρολόγιο. Συνάρτηση Binary-Search(Ε[],N,K ) L=1,U=N,ex=0,index=0 Όσο L U και ex == 0 επανάλαβε i= (L+U)/2 Αν K == Ε[i] τότε ex = 1 index = i αλλιώς_αν K < Ε[i] τότε U = i-1 αλλιώς L = i+1 Τέλος_αν Τέλος_επανάληψης Εμφάνισε τις τιμές των: // ex,index// Τέλος Binary - Search Συνάρτηση main Δήλωσε τον πίνακα Κ με μέγεθος 10 στοιχεία ακέραιου τύπου; Δήλωσε την μεταβλητή key, ακέραιου τύπου; Διάβασε το key από το πληκτρολόγιο; Διάβασε τα στοιχεία το πίνακα Κ από το πληκτρολόγιο; Κάλεσε την συνάρτηση BinarySearch με ορίσματα Κ,10 και key; Τελος main

Ταξινόμηση Στην παρακάτω άσκηση θα εξετάσουμε τον αλγόριθμο τξινόμησης που καλείται Ταξινόμηση με επιλογή (Selection Sort). Στην Πληροφορική, η Ταξινόμηση με επιλογή είναι ένας αλγόριθμος ταξινόμησης. Η πολυπλοκότητα του είνα Ο(n 2 ), κάτι που τον κάνει αναποτελεσματικό σε μεγάλες λίστες (πίνακες). Ωστόσο, είναι γνωστός για την απλότητα του, και σε κάποιες περιπτώσεις είναι πιο αποτελεσματικός από πιο σύνθετους αλγορίθμους. Algorithm - Αλγόριθμος Ο αλγόριθμος λειτουργεί ως εξής: 1. Βρίσκει το ελάχιστο στοιχείο στον πίνακα 2. Αντιμεταθέτει την τιμή του ελάχιστου στοιχείου με την τιμή στην πρώτη θέση του πίνακα 3. Επαναλαμβάνει τα βήματα 1 και 2 στο υπόλοιπο του πίνακα Ο πίνακας διαιρείται σε δύο τμήματα: σε ένα τμήμα τα στοιχεία είναι ταξινομημένα, το οποίο δημιουργείται από αριστερά προς τα δεξία και ξεκινάει από την αρχή του πίνακα, και στο άλλο τμήμα του πίνακα όπου βρίσκονται τα αταξινόμητα στοιχεία του πίνακα Παρακάτω δίνεται ένα παράδειγμα του αλγορίθμου και πως δουλεύει βήμα-βήμα. 64 25 12 22 11 Ελάχιστο: (Τιμή 11, Θέση 5) Αντιμετάθεση με (Τιμή 64, Θέση 1) 11 25 12 22 64 Ελάχιστο: (Τιμή 12, Θέση 3) Αντιμετάθεση με (Τιμή 25, Θέση 2) 11 12 25 22 64 Ελάχιστο: (Τιμή 22, Θέση 4) Αντιμετάθεση με (Τιμή 25, Θέση 4) 11 12 22 25 64 Ελάχιστο: (Τιμή 25, Θέση 4) Αντιμετάθεση με - 11 12 22 25 64 Τέλος αλγορίθμου Παρακάτω δίνεται ο ψευδοκώδικας όπου περιγράφεται η ταξινόμηση με επιλογή. Να γραφεί πρόγραμμα όπου θα υλοποιεί σε C++ τον παρακάτω αλγόριθμο. Επίσης να δοκιμάσετε τον αλγόριθμο στον πίνακα 64,25,12,22,11 και στον πίνακα 44, 55, 12, 42, 94, 18, 06, 67. Αλγόριθμος Selection-Sort Δεδομένα // A[],N // Για i από 1 μέχρι N με_βήμα 1 Διάβασε Α[i] Τέλος_επανάληψης Για i από 1 μέχρι N με_βήμα 1 x = A[i] k = i Για j από i μέχρι N με_βήμα 1 Αν A[j]<x τότε k = j x = A[j]

Τέλος_αν Τέλος_επανάληψης Αντιμετάθεσε A[i],A[k] Τέλος_επανάληψης Για i από 1 μέχρι N με_βήμα 1 Εκτύπωσε Α[i] Τέλος_επανάληψης Τέλος Selection-Sort

3 η Εργαστηριακή Άσκηση Στοίβα και ουρά Στοίβα Η ιδέα της στοίβας συναντάται συχνά στην καθημερινή μας ζωή. Παραδείγματα που συναντάμε στην καθημερινή μας ζωή είναι μια στοίβα απο πιάτα, η θήκη κερμάτων. Αν παρατηρήσουμε τον τρόπο με το οποίο λειτουργεί μια στοίβα βασιζόμενοι στα καθημερινά πραδείγματα θα δούμε ότι: το τελευταίο στοιχείο που μπήκε στη στοίβα είναι και το πρώτο που φεύγει. Η παραπάνω διαδικασία καλείται LIFO (Last In First Out). Μια πιο αυστηρή περιγραφή της στοίβας δίνεται από τον παρακάτω ορισμό: Μια στοίβα (stack) είναι μια γραμμική διάταξη στοιχείων, στην οποία νέα στοιχεία μπορούν να ενταχθούν ή στοιχεία που υπάρχουν να εξαχθούν μόνο από το ένα άκρο (κεφαλή της στοίβας). Οι βασικές λειτουργίες σε μια στοίβα είναι η εισαγωγή και εξαγωγή στοιχείων στην στοίβα. Η Εισαγωγή στοιχείου στη στοίβα καλείται και Ώθηση (push Εισαγωγή Στοιχείου), ενώ η εξαγωγή ενός στοιχείου καλείται και Απώθηση (pop Εξαγωγή Στοιχείου). Θεωρητικά μια στοίβα δεν έχει περιορισμό ως προς τον αριθμό των στοιχείων που μπορεί να δεχθεί. Ώστοσο, για την υλοποίηση της σε πρόγραμμα υπολογιστή θα πρέπει να θέσουμε κάποιους περιορισμούς ώς προς το μέγεθος της στοίβας καθώς η μνήμη του υπολογιστή δεν είναι άπειρη (ή απεριοριστή). Για την υλοποίηση μιας στοίβας θα χρησιμοποιήσουμε έναν στατικό πίνακα. Καθώς ο πίνακας έχει σταθερό μέγεθος, το ίδιο θα συμβαίνει και με την στοιβα. Στην Εικόνα 1 βλέπουμε ένα παράδειγμα μιας στοίβας όπου υλοποιείται με χρήση ενός στατικού πίνακα.

Εικόνα 1: Παράδειγμα Στοίβασ - Ειςαγωγι και Εξαγωγι Στοιχείου Υποθέτωντας ότι η στοίβα υλοποιείται σε ένα πίνακα με όνομα Stack και μέγεθος Ν, ο ψευδοκώδικάς για τις λειτουργίες την ώθησης και της απώθησης δίνεται στην παρακάτω ψευδοσυναρτήσεις: Συνάρτηση Push(item,flag) Αν head < N τότε head = head + 1 Stack[head] = item flag = 1 αλλιώς flag = 0 Τέλος_αν Αποτελέσματα // flag // Τέλος Push Συνάρτηση Pop(item,flag) Αν head > 0 τότε item = Stack[head] head = head - 1 flag = 1 αλλιώς flag = 0 Τέλος_αν Αποτελέσματα // item, flag // Τέλος Pop Σκοπός της εργαστηριακής άσκησης είναι να αποκτήσουμε οικειότητα με τις λειτουργίες της στοίβας, αλλά και να δούμε διάφορους τρόπους υλοποίησης

αυτών. Παρακάτω σας δίδεται ένα πρόγραμμα γραμμένο σε C++ όπου θα πρέπει να συμπληρωθεί ο κώδικας για την λειτουργία της ώθησης (push). #include "stdafx.h" #include <iostream> using namespace std; int stack[10]; int head; int flag; int pop(); void push(int item); int main() int i; int temp; head = -1; push(3); push(4); push(8); //Tiponoume tin stoiba for (i=0;i<=head;i++) cout<<stack[i]<<" "; cout<<endl; temp = pop(); temp = pop(); //Tiponoume tin stoiba for (i=0;i<=head;i++) cout<<stack[i]<<" "; cout<<endl; return 0;

int pop() int item; if (head>-1) item = stack[head]; head--; flag = 1; else flag = 0; return item; void push(int item) Ουρά Η ουρά είναι μια άλλη απλή δομή δεδομένων. Μια ουρά δημιουργείται όταν άνθρωποι, εργασίες, κτλ πρέπει να περιμένουν για κάποια εξυπηρέτηση (ουρά αναμονής). Η λειτουργία της ουράς βασίζεται στην εξής διαδικασία: το πρώτο στοιχείο της ουρά είναι και το πρώτο που εξυπηρετείται. Η μέθοδος αυτή καλείται και FIFO (First In First Out). Η υλοποίηση μιας ουράς γίνεται συνήθως με την χρήση ενός πίνακα ή μιας γραμμικής λίστας. Στο παράδειγμα μας θα ασχοληθούμε με την υλοποίηση της ουράς χρησιμοποιώντας ένα στατικό πίνακα. Η χρήση πίνακα για την υλοποίηση της ουράς θέτει περιορισμό ως προς το μέγεθος της ουράς. Αυτό έχει ως συνέπεια κατά την διαδικασία εισαγωγής ενός στοιχείου να πρέπει να κάνουμε έλεγχο για το αν υπάρχει χώρος για αυτό το στοιχείο. Όπως και στην στοίβα, έτσι και στην ουρά, οι βασικές λειτουργίες πάνω σε αυτή τη δομή δεδομένων είναι η εισαγωγή (enqueue) και εξαγωγή (dequeue) ενός στοιχείου. Για την υλοποίηση της ουράς θα χρησιμοποιήσουμε ένα πίνακα με όνομα Queue και μέγεθος Ν. Στην εικόνα 2 βλέπουμε ένα παράδειγμα μιας ουράς.

Εικόνα 2: Παράδειγμα Ουράσ - Ειςαγωγι ςτοιχείων και Εξαγωγι ςτοιχείων Μπορούμε να παρατηρήσουμε ότι η ουρά χρειάζεται ένα δείκτη για την εισαγωγή ενός στοιχείου (rear) και ένα δείκτη για την εξαγωγή ενός στοιχείου (front). Ενώ, η στοίβα χρησιμοποιούσε ένα δείκτη (head) και για τις δύο λειτουργίες. Υποθέτωντας ότι η ουρά υλοποιείται σε ένα πίνακα με όνομα stack και μέγεθος Ν, ο ψευδοκώδικάς για τις λειτουργίες της εισαγωγής και της εξαγωγής ενός στοιχείου δίνεται από τις παρακάτω ψευδοσυναρτήσεις: Συνάρτηση Enqueue(item,flag) Αν front == 0 τότε front = 1 Τέλος_αν Αν rear N τότε rear = rear + 1 Queue[rear] = item flag = 1 /*Αληθής*/ αλλιώς flag = 0 /*Ψευδής*/ Τέλος_αν Αποτελέσματα // flag // Τέλος Enqueue

Συνάρτηση Dequeue(item,flag) Αν front 0 τότε item = Queue[front] front = front + 1 flag = 1 /*Αληθής*/ Αν front > rear τότε rear = 0 front = 0 Τέλος_αν αλλιώς flag = 0 /*Ψευδής*/ Τέλος_αν Αποτελέσματα // item,flag // Τέλος Dequeue Παρακάτω σας δίδεται ένα πρόγραμμα γραμμένο σε C++ όπου υλοποιείται η στοίβα. Ωστόσο, για να λειτουργεί το πρόγραμμα θα πρέπει να συμπληρωθεί ο κώδικας για την λειτουργία της εξαγωγής (dequeue) ενός στοιχείου από την στοίβα. #include "stdafx.h" #include <iostream> using namespace std; int queue[10]; int rear; int front; int flag; int dequeue(); void enqueue(int item); int main() int item; int i; rear = -1; front = -1;

enqueue(12); enqueue(11); enqueue(21); item = dequeue(); cout<<item<<endl; item = dequeue(); cout<<item<<endl; item = dequeue(); cout<<item<<endl; return 0; void enqueue(int item) if (front == -1) front = 0; if (rear <= 9) rear++; queue[rear]=item; flag = 1; else flag = 0; int dequeue()

Δομζσ Δεδομζνων 4 θ Εργαςτθριακι Άςκθςθ Η παροφςα εργαςτθριακι άςκθςθ αςχολείται με τισ ςυνδεδεμζνεσ λίςτεσ. Κοινό χαρακτθριςτικό των δομϊν που εξετάςτθκαν μζχρι τϊρα (πίνακεσ, ουρζσ και ςτοίβεσ) είναι ότι οι διαδοχικοί κόμβοι των δομϊν αποκθκεφονται ςε ςυνεχόμενεσ κζςεισ μνιμθσ. Οι δομζσ αυτζσ παρουςιάηουν πρόβλθμα τόςο ςτθν ειςαγωγι και διαγραφι κόμβων, όςο και ςτθν αποδοτικι εκμετάλευςθ τθσ διακζςιμθσ μνιμθσ. Μια εναλλακτικι υλοποίθςθ των παραπάνω δομϊν μπορεί να επιτευχκεί με τθν χριςθ των ςυνδεδεμζνων λιςτϊν. Κφριο χαρακτθριςτικό των ςυνδεδεμζνων λιςτϊν είναι ότι οι κόμβοι βρίςκονται ςε απομακρυςμζνεσ κζςεισ μνιμθσ και θ ςφνδεςθ του γίνεται με δείκτεσ. Με τον τρόπο αυτό διευκολφνεται θ ειςαγωγι και διαγραφι δεδομζνων. Επίςθσ, δεν απαιτείται να είναι γνωςτόσ εκ των προτζρων ο μζγιςτοσ αρικμόσ των κόμβων τθσ λίςτασ. Βαςικό ςυςτατικό των ςυνδεδεμζνων λιςτϊν αποτελεί ο κόμβοσ, οποίοσ αποτελείται από δφο μζρθ, τα δεδομζνα και τον δείκτθ. Δφο βαςικά χαρακτθριςτικά μιασ λίςτασ κα πρζπει να λαμβάνονται πάντα υπόψιν: Η κζςθ του πρϊτου κόμβου είναι γνωςτι Ο δείκτθσ ςτον τελευταίο κόμβο «δείχνει» ςτον nil (κενό δείκτθ null ςτθ C++) Στα παραδείγματα μασ ο κόμβοσ για εμάσ κα είναι μια δομι (struct) με δφο μζλθ, info και next. Το μζλοσ info περιζχει τα δεδομζνα, που για εμάσ κα είναι τφπου ακεραίου, και το μζλοσ next είναι ζνασ δείκτθσ ςε μια άλλθ δομι ιδίου τφπου (Εικόνα 1). P.info P.next Εικόνα 1. Κόμβοσ Εικόνα 2 Παράδειγμα Συνδεδεμζνθσ λίςτασ Σε μια ςυνδεδμζνθ λίςτα (Εικόνα 2.) μποροφμε να εκτελζςουμε τισ παρακάτω λειτουργίεσ

Αναηιτθςθ Ειςαγωγι Διαγραφι Συνζνωςθ Αντιςτροφι Στθν παροφςα άςκθςθ κα αςχολθκοφμε με τισ λειτουργίεσ τθσ αναηιτθςθσ και ειςαγωγισ ενόσ ςτοιχείου ςε μια λίςτα. Αναηιτθςθ Στοιχείου ςε Συνδεδεμζνθ λίςτα Αναηιτθςθ είναι θ εφρεςθ ενόσ ςτοιχείου ςτθ λίςτα, αν υπάρχει. Βαςίηεται ςτθ διάςχιςθ των δεδομζνων τθσ λίςτασ μζςω των δεικτϊν. Ο αλγόρικμοσ διατρζχει διαδοχικά τθ λίςτα μζχρι να βρεί τον ηθτοφμενο κόμβο. Τα δεδομζνα είναι: ζνασ δείκτθσ που δείχνει ςτον πρϊτο κόμβο και μια μεταβλθτι τθσ οποίασ θ τιμι τθσ αναηθτείται ωσ περιεχόμενο κάποιου κόμβο Αλγόρικμοσ SearchList Δεδομζνα // Start, item// P = Start found = false position = nil Όςο P nil και found == false επανάλαβε Αν P.info == item τότε found = true position = P αλλιϊσ P = P.next Τζλοσ_αν Τζλοσ_επανάλθψθσ Αποτελζςματα // found, position// Τζλοσ SearchList

Ειςαγωγι νζου κόμβου ςτθ λίςτα Εικόνα 3 Σχθματικι Αναπαράςταςθ Ειςαγωγισ Νζου Κόμβου ςε μια Συνδεδεμζνθ λίςτα Στθν εικόνα 3 βλζπουμε μια ςχθματικι αναπαράςταςθ τθσ ειςαγωγισ ενόσ νζου κόμβου ςε μια λίςτα. Αρχικά κα πρζπει να γνωρίηουμε τον κόμβο node, μετά τόν οποίο κα πρζπει να τοποκετιςουμε τον κόμβο newnode. Ο αλγόρικμοσ για τθν ειςαγωγι του νζου κόμβου είναι: Αλγόρικμοσ InsertList Δεδομζνα // P,item,NewNode// NewNode.info = item NewNode.next = P.next P.next = NewNode Τζλοσ InsertList Παρακάτω ςασ δίνεται ζνα ολοκλθρωμζνο πρόγραμμα που αφορά τισ ςυνδεδεμζνεσ λίςτεσ. Θα πρζπει να ςυμπλθρϊςετε τον κϊδικα για τισ ςυναρτιςεισ insertnode και FindNode, που αφοροφν τισ λειτουργίεσ Ειςαγωγι Στοιχείου και Αναηιτθςθ Στοιχείου ςε μια λίςτα, αντίςτοιχα. Για να ςυμπλθρϊςετε τον κϊδικα ςυμβουλευτείτε τουσ αλγορίκμουσ που ςασ δίνονται παραπάνω. #include "stdafx.h" #include <iostream> using namespace std; struct node int info; node *next; ; //Δεδομένα //Δείκτησ για τον επόμενο κόμβο void insertnode(node *P,int item);//ειςαγωγή νέου κόμβου node* FindNode(node *start, int key);//εύρεςη κόμβο με //δεδομένα = key int LengthList(node *start); //Μήκοσ Λίςτασ

void CreateList(node *start,int item1,int item2,int item3);//δημιουργία μιασ λίςτασ με 3 κόμβουσ void printlistinfo(node *s);//εκτύπωςη των δεδομένων τησ //λίςτασ. int main() node *List=new node; node *temp; CreateList(List,23,2,3); printlistinfo(list); cout<<"len:"<<lengthlist(list)<<endl; insertnode(list,5); printlistinfo(list); temp = FindNode(List,2); insertnode(temp,14); printlistinfo(list); return 0; int LengthList(node *start) node *p=start; int count = 0; while (p!= 0) count++; p=p->next; return count; void CreateList(node *start,int item1,int item2,int item3) node *s2 = new node; node *s3 = new node; start->info = item1; start->next = s2; s2->info = item2; s2->next = s3; s3->info = item3; s3->next = 0; void insertnode(node *P,int item)

node* FindNode(node *start,int key) void printlistinfo(node *s) node *p=s; while (p!= 0) cout<<"node:"<<p->info<<endl; p=p->next;

5 η Εργαστηριακή Άσκηση Δέντρα Οι προηγούμενες δομές που εξετάστηκαν λέγονται γραμμικές διότι διαθέτουν τη σχέση της συνεχόμενης λογικής γειτονικότητας των στοιχείων τους. Σε αυτήν την άσκηση θα εξετάσουμε μια μη γραμμική δομή, τα δέντρα. Η δομή του δέντρου σε γενικές γραμμές δεν είναι τίποτε άλλο παρά η σύνδεση κόμβων με τρόπο ανάλογο ενός πραγματικού δέντρου. Δέντρο είναι ένα σύνολο κόμβων που συνδέονται με ακμές. Υπάρχει ένας μόνο κόμβος που ονομάζεται ρίζα και στον οποίο δεν καταλήγουν αλλά μόνο ξεκινούν ακμές. Από κάθε κόμβο μπορούν να ξεκινούν, καμία, μία ή περισσότερες ακμές. Σε κάθε κόμβο (εκτός της ρίζας) καταλήγει μόνο μία ακμή (Εικόνα 1). Εικόνα 3 : Δυαδικό δζντρο Τα δυαδικά δέντρα αναζήτησης είναι διατεταγμένα δέντρα στα οποία ένας κόμβος μπορεί να έχει μέχρι δύο παιδιά. Διατεταγμένο δέντρο λέγεται το δέντρο στο οποίο έχει σημασία η διάταξη των παιδιών κάθε κόμβου, ενώ δέντρο αναζήτησης είναι το δέντρο, του οποίου η τιμή κάθε κόμβου είναι μεγαλύτερη από την τιμή όλων των κόμβων του αριστερού υπόδεντρου και μικρότερη από την τιμή όλων των κόμβων το δεξιού υπόδεντρου. Στις εικόνες 2 και 3 δείχνονται κάποια έγκυρα και μη έγκυρα δυαδικά δέντρα αναζήτησης.

Εικόνα 4 Ζγκυρα Δυαδικά Δζντρα Αναηιτθςθσ Εικόνα 5 Μθ ζγκυρα δυαδικά δζντρα αναηιτθςθσ Στην παρούσα άσκηση θα εξετάσουμε δύο λειτουργίες που πρέπει να μπορούμε να κάνουμε σε δυαδικά δέντρα αναζήτησης, την εισαγωγή ενός κόμβου στο δέντρο και την αναζήτηση ενός κόμβου στο δέντρο. Η βασική ιδέα είναι ίδια και στους δύο αλγόριθμους που θα παρουσιαστούν παρακάτω. Αναζήτηση κόμβου Για την εύρεση ενός κόμβο σε δυαδικό δέντρο αναζήτησης εφαρμόζουμε τον παρακάτω αλγόριθμο: 1. Εξετάζουμε τη ρίζα σε σχέση με το κλειδί αναζήτησης 2. Αν ο ζητούμενος κόμβος έχει: a. μικρότερη τιμή από τη ρίζα συνεχίζουμε με το αριστερό υπόδεντρο

b. μεγαλύτερη τιμή από τη ρίζα συνεχίζουμε με το δεξί υπόδεντρο 3. Η αναζήτηση σταματά αν βρεθεί ο ζητούμενος κόμβος ή φτάσουμε σε κενό δείκτη Ο ψευδοαλγόριθμος δίνεται παρακάτω: Αλγόριθμος Search-Node Δεδομένα // Root,Key// P = Root found = false position = nil Όσο P nil και found == false Αν Key == P.info τότε found = false position = P αλλιώς_αν Key > P.info τότε P = P.right αλλιώς P = P.left Τέλος_αν Τέλος_επανάληψης Αποτελέσματα // found, position// Τέλος Search-Node Εισαγωγή κόμβου Σε ένα δέντρο αναζήτησης οι νέοι κόμβοι εντάσσονται ως τερματικοί κόμβοι. Αρχικά ακολουθείται η διαδικασία της αναζήτησης αναζητώντας τον κόμβο που πρέπει να προστεθεί. Ο κόμβος φυσικά δεν θα υπάρχει και θα βρεθεί ένας κενός δείκτης ο κόμβος προστίθεται με τρόπο ώστε ο κενός δείκτης τώρα θα δείχνει σ αυτόν. Παρατηρείστε ότι εφαρμόζονται τα ίδια βήματα με αυτά του αλγορίθμου αναζήτησης. Αλγόριθμος InsertNode Δεδομένα // Root, item// /* Create new node*/ NewNode.Info = item NewNode.left=nil NewNode.right=nil P = Root Όσο P nil επανάλαβε parentnode = P Αν NewNode.Info > P.Info τότε P = P.right

αλλιώς P = P.left Τέλος_αν Τέλος_επανάληψης Αν NewNode.Info > parentnode.info τότε parentnode.right = NewNode αλλιώς parentnode.left = NewNode Τέλος_αν Τέλος InsertNode Στην παρακάτω εικόνα βλέπουμε σχηματικά τα διάφορα βήματα του αλγορίθμου για την εισαγωγή του κόμβου με δεδομένα τον ακέραιο 6 στο τρέχων δέντρο. Παρακάτω σας δίνεται ένα ολοκληρωμένο πρόγραμμα που αφορά τα δυαδικά δέντρα αναζήτησης. Θα πρέπει να συμπληρώσετε τον κώδικα για τις συναρτήσεις ΙnsertNode και SearchTree, που αφορούν τις λειτουργίες Εισαγωγή Κόμβου και Αναζήτηση Κόμβου σε ένα δυαδικό δέντρο αναζήτησης, αντίστοιχα. Για να συμπληρώσετε τον κώδικα συμβουλευτείτε τους αλγορίθμους που σας δίνονται παραπάνω.

#include "stdafx.h" #include <iostream> using namespace std; struct tree_node int info; tree_node *rightchild; tree_node *leftchild; ; void create_tree(tree_node *proot); tree_node* SearchTree(tree_node *proot,int key); void InsertNode(tree_node *proot,int item); void printtree(tree_node *proot); int main() tree_node *root = new tree_node; tree_node *temp; create_tree(root); cout<<"ektiposi dentrou:"<<endl; printtree(root); temp = SearchTree(root,30); cout<<temp->info<<endl; InsertNode(root,5); cout<<"ektiposi dentrou:"<<endl; printtree(root); return 0; void create_tree(tree_node *proot) tree_node *rchild,*lchild; proot->info= 21; rchild = new tree_node; rchild->info = 30; rchild->rightchild = 0; rchild->leftchild = 0; lchild = new tree_node; lchild->info = 6; lchild->rightchild = 0; lchild->leftchild = 0;

proot->leftchild = lchild; proot->rightchild = rchild; tree_node* SearchTree(tree_node *proot,int key) void InsertNode(tree_node *proot,int item) void printtree(tree_node *proot) tree_node *p; p = proot; if ( p!= 0) cout<<p->info<<endl; printtree(p->leftchild); printtree(p->rightchild);

6 η Εργαστηριακή Άσκηση Αλγόριθμοι Διάσχισης Δυαδικών Δέντρων Στην πληροφορική, η διάσχιση δέντρου αναφέρεται στη διαδικασία επίσκεψης (εξέτασης και/ή ενημέρωσης) του κάθε κόμβου που υπάρχει στο δέντρο, ακριβώς μια φορά, με συστηματικό τρόπο. Τέτοιες διαδικασίες διάσχισης κατηγοριοποιούνται σε σχέση με την σειρά επίσκεψης των κόμβων. Οι παρακάτω αλγόριθμοι περιγράφονται για ένα δυαδικό δέντρο αλλά μπορούν να γενικευθούν και σε άλλα είδη δέντρων. Σε σύγκριση με τις γραμμικές δομές δεδομένων όπως είναι οι συνδεδεμένες λίστες και οι πίνακες, οι οποίες έχουν μια τυπική μέθοδο διάσχισης, οι δενδρικές δομές δεδομένων μπορούν να διασχισθούν με πολλούς διαφορετικούς τρόπους. Ξεκινώντας από τη ρίζα ενός δυαδικού δέντρου, υπάρχουν τρία βασικά βήματα που μπορούν να πραγματοποιηθούν και η σειρά με την οποία εκτελούνται τα βήματα καθορίζει τον τύπο διάσχισης. Αυτά τα βήματα (χωρίς ιδιαίτερη σειρά) είναι: να εκτελέσετε κάποια ενέργεια για το τρέχον κόμβο, επίσκεψη του αριστερού παιδιού, και επίσκεψη του δεξιού παιδιού. Είναι εμφανές ότι η παραπάνω διαδικασία είναι πιο εύκολο να περιγραφεί με αναδρομή. Πιο συγκεκριμένα, υπάρχουν 3 διαφορετικοί τρόποι επίσκεψης των κόμβων. Κάθε τρόπος απαιτεί την εκτέλεση των επόμενων τριών βημάτων με κάποια σειρά: 1. Επίσκεψη ρίζας 2. Επίσκεψη αριστερού υποδέντρου 3. Επίσκεψη δεξιού υποδέντρου Οι διαδικασίες 2 και 3 απαιτούν την επίσκεψη ενός υποδέντρου, που μπορεί να γίνει επαναλαμβάνοντας τις ίδιες διαδικασίες με την ίδια σειρά. Στην προδιαταγμενή διάσχιση τα βήματα εκτελούνται με τη σειρά 1, 2, και 3. Έτσι, για το δέντρο της Εικόνας 1, η σειρά επίσκεψης των κόμβων γίνεται ως εξής: F, B, A, D, C, E, G, I, H Στην μεταδιαταγμένη διάσχιση τα βήματα εκτελούνται με τη σειρά 2, 3 και 1. Έτσι, για το δέντρο της Εικόνας 1, η σειρά επίσκεψης των κόμβων γίνεται ως εξής: A, C, E, D, B, H, I, G, F Στην ενδοδιαταγμένη διάσχιση τα βήματα εκτελούνται με τη σειρά 2, 1 και 3. Έτσι, για το δέντρο της Εικόνας 1, η σειρά επίσκεψης των κόμβων γίνεται ως εξής: A, B, C, D, E, F, G, H, I

Εικόνα 6: Παράδειγμα Δυαδικοφ Δζντρου Παρακάτω σας δίνεται ένα ολοκληρωμένο πρόγραμμα που αφορά τα δυαδικά δέντρα αναζήτησης και τρόπους διάσχισης αυτών. Σκοπός σας είναι να υλοποιήσετε τους προαναφερόμενους τρόπους διάσχισης δυαδικών δέντρων. Πιο συγκεκριμένα θα πρέπει να υλοποιήσετε 2 συναρτήσεις που θα τυπώνουν το πεδίο info του κάθε κόμβου στην οθόνη συμφωνα με την μεταδιατεταγμένη και ενδοδιατεταγμένη διάσχιση. Η συνάρτηση printtree που σας δίνεται υλοποιεί την προδιατεταγμένη διάσχιση. Επίσης, θα πρέπει να προσαρμόσετε την main συνάρτηση ώστε να κατασκευάσετε το δέντρο που περιγράφεται στην εικονα 2. Εικόνα 7: Δυαδικό δζντρο για τθν άςκθςθ

#include "stdafx.h" #include <iostream> using namespace std; struct tree_node int info; tree_node *rightchild; tree_node *leftchild; ; void create_tree(tree_node *proot,int item1,int item2,int item3); void InsertNode(tree_node *proot,int item); void printtree(tree_node *proot); int main() tree_node *root = new tree_node; create_tree(root,15,10,20); cout<<"ektiposi dentrou:"<<endl; printtree(root); InsertNode(root,2); cout<<"ektiposi dentrou:"<<endl; printtree(root); return 0; void create_tree(tree_node *proot,int item1,int item2,int item3) tree_node *rchild,*lchild; proot->info= item1; rchild = new tree_node; rchild->info = item3; rchild->rightchild = 0; rchild->leftchild = 0; lchild = new tree_node; lchild->info = item2; lchild->rightchild = 0; lchild->leftchild = 0; proot->leftchild = lchild; proot->rightchild = rchild; void InsertNode(tree_node *proot,int item) tree_node *parentnode,*p; tree_node *NewNode = new tree_node;

NewNode->info = item; NewNode->leftchild = 0; NewNode->rightchild = 0; p = proot; while (p!=0) parentnode = p; if (NewNode->info > p->info) p = p->rightchild; else p = p->leftchild; if (NewNode->info > parentnode->info) parentnode->rightchild = NewNode; else parentnode->leftchild = NewNode; void printtree(tree_node *proot) tree_node *p; p = proot; if ( p!= 0) cout<<p->info<<endl; printtree(p->leftchild); printtree(p->rightchild); Δομζσ Δεδομζνων 7 θ Εργαςτθριακι Άςκθςθ Διαγραφι κόμβου από δυαδικό δζντρο

Η διαγραφι ενόσ κόμβου ςε δυαδικό δζντρο είναι πιο δφςκολθ διαδικαςία απ ότι θ ειςαγωγι ενόσ κόμβου. Κατά τθν διαδικαςία διαγραφισ ενόσ κόμβου από ζνα δυαδικό δζντρο διακρίνουμε τρεισ περιπτϊςεισ: 1. Αν ο κόμβοσ είναι φφλλο, τότε απλϊσ διαγράφεται. 2. Αν ο κόμβοσ ζχει μόνο ζνα παιδί, το οποίο είναι φφλλο, τότε αντικακίςταται από τον κόμβο παιδί. 3. Αν όμωσ ζχει δφο παιδιά, τότε αντικακίςταται με τον κόμβο με το επόμενο μεγαλφτερο κλειδί. Στθν παροφςα άςκθςθ κα εξετάςουμε τισ δφο πρϊτεσ περιπτϊςεισ. Περίπτωςθ 1. Κόμβοσ Φφλλο Η περίπτωςθ 1 είναι θ πιο απλι και εφκολθ περίπτωςθ. Όταν ο προσ διαγραφι κόμβοσ είναι φφλλο τότε απλϊσ διαγράφεται. Για να διαγράψουμε ζνα φφλλο από το δζντρο πρζπει να ο γονζασ του προσ διαγραφι κόμβου να μθν δείχνει ςτον κόμβο αλλά ςτον κενό δείκτθ (Εικονα 1). Εικόνα 8: Διαγραφι κόμβου - Περίπτωςθ 1 Στο παράδειγμα τθσ εικόνασ 1 κα πρζπει το αριςτερό παιδί του κόμβου με τιμι 5 να δείχνει ςτον κενό δείκτθ για να ζχουμε διαγραφι του κόμβου 3. Γενικά ο ψευδοαλγόρικμοσ για τθν διαγραφι ενόσ κόμβου ςτθν περίπτωςθ 1 περιγράφεται από: Εάν currentνode είναι αριςτερό παιδί αλλιϊσ parentnode.leftchild = nil parentnode.rightchild = nil

όπου currentnode είναι ο κόμβοσ που κζλουμε να διαγράψουμε και parentnode είναι ο γονζασ του. Περίπτωςθ 2. Κόμβοσ με ζνα παιδί Στθν περίπτωςθ 2 ο κόμβοσ που κα διαγραφεί ζχει δφο ςυνδζςεισ, μια με τον πατζρα του και μια με το παιδί του. Συνδζουμε απευκείασ τον πατζρα του κόμβου με τον παιδί του κόμβου (εγγονό) (Εικόνα 2). Εικόνα 9: Διαγραφι Κόμβου - Περίπτωςθ 2 Σκοπόσ τθσ παροφςασ εργαςίασ είναι να δθμιουργιςετε μια ςυνάρτθςθ με όνομα DelNode θ οποία κα υλοποιεί τισ δφο προαναφερκείςεσ περιπτϊςεισ για τθν διαγραφι ενόσ κόμβου. Η ςυνάρτθςθ κα δζχεται ωσ ορίςματα: τθν ρίηα του δζντρου (root), τθν τιμι του πεδίου info του προσ διαγραφι κόμβου (key), και μια βοθκθτικι μεταβλθτι που κα μασ λζει ποια περίπτωςθ κα πρζπει να εφαρμόςουμε (1: περίπτωςθ 1, 2: περίπτωςθ 2). Αρχικά ξεκινϊντασ από τθν ρίηα του δζντρου κα πρζπει να βρείτε τον κόμβο που κζλετε να διαγράψεται, κακϊσ και τον πατζρα και/ι τα παιδιά του. #include "stdafx.h" #include <iostream> using namespace std; struct tree_node int info; tree_node *rightchild; tree_node *leftchild; ; void create_tree(tree_node *proot); tree_node* SearchTree(tree_node *proot,int key); void InsertNode(tree_node *proot,int item); void printtree(tree_node *proot); void DelNode(tree_node *root,int key,int flag); int main()

tree_node *root = new tree_node; tree_node *temp; create_tree(root); cout<<"ektiposi dentrou:"<<endl; printtree(root); InsertNode(root,1); InsertNode(root,5); InsertNode(root,6); cout<<"ektiposi dentrou:"<<endl; printtree(root); DelNode(root,5,2); cout<<"ektiposi dentrou:"<<endl; printtree(root); return 0; void create_tree(tree_node *proot) tree_node *rchild,*lchild; proot->info= 7; rchild = new tree_node; rchild->info = 9; rchild->rightchild = 0; rchild->leftchild = 0; lchild = new tree_node; lchild->info = 2; lchild->rightchild = 0; lchild->leftchild = 0; proot->leftchild = lchild; proot->rightchild = rchild; tree_node* SearchTree(tree_node *proot,int key) tree_node *p,*position; int found; p = proot; found = 0; position = 0; while (p!=0 && found == 0)

if (key == p->info) found = 1; position = p; else if (key>p->info) p = p->rightchild; else p = p->leftchild; return position; void InsertNode(tree_node *proot,int item) tree_node *parentnode,*p; tree_node *NewNode = new tree_node; NewNode->info = item; NewNode->leftchild = 0; NewNode->rightchild = 0; p = proot; while (p!=0) parentnode = p; if (NewNode->info > p->info) p = p->rightchild; else p = p->leftchild; if (NewNode->info > parentnode->info) parentnode->rightchild = NewNode; else parentnode->leftchild = NewNode;

void printtree(tree_node *proot) tree_node *p; p = proot; if ( p!= 0) cout<<p->info<<endl; printtree(p->leftchild); printtree(p->rightchild); void DelNode(tree_node *root,int key, int flag)