You are on page 1of 15

Ε.Α.Π.

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


4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ

ΑΚΑΔΗΜΑΪΚΟΥ ΕΤΟΥΣ 2019-2020

3ος Τόμος

ΕΙΣΑΓΩΓΗ ΣΤΗΝ ΕΠΙΣΤΗΜΗ ΤΩΝ ΥΠΟΛΟΓΙΣΤΩΝ

13/3/2020

Ημερομηνία παράδοσης εργασίας: Κυριακή 03/05/2020


Καταληκτική ημερομηνία παραλαβής: Τετάρτη1 06/05/2020
Ημερομηνία ανάρτησης ενδεικτικών λύσεων: Σάββατο 09/05/2020
Καταληκτική ημερομηνία αποστολής σχολίων στον φοιτητή: Κυριακή 24/05/2020

ΥΠΟΕΡΓΑΣΙΑ 1. (βαθμοί 25)


Πίνακες δύο διαστάσεων

ΥΠΟΕΡΓΑΣΙΑ 2. (βαθμοί 25)


Συνδεδεμένες λίστες, πίνακες μίας διαστάσεως

ΥΠΟΕΡΓΑΣΙΑ 3. (βαθμοί 25)


Δυαδικά δέντρα αναζήτησης και δέντρα-σωροί

ΥΠΟΕΡΓΑΣΙΑ 4. (βαθμοί 25)


Συνδεδεμένες λίστες, αραιοί πίνακες

ΣΥΝΟΛΟ (βαθμοί 100)

1
Σύμφωνα με τον Κανονισμό Σπουδών, η καταληκτική ημερομηνία για την παραλαβή της Γ.Ε. από το μέλος
ΣΕΠ είναι η επόμενη Τετάρτη από το τέλος της εβδομάδας παράδοσης Γ.Ε.
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

ΥΠΟΕΡΓΑΣΙΑ 1 (βαθμοί 25)


Στα μαθηματικά, μια αλγεβρική παράσταση με δύο όρους, λέγεται διώνυμο. Π.χ. το (1+a), το
(x+y) είναι διώνυμα. Υψώνοντας το διώνυμο σε κάποια ακέραια δύναμη n, n>1, λαμβάνουμε
ένα πολυώνυμο βαθμού n, π.χ. το (x+y)n. Κάνοντας τις πράξεις, δηλαδή αναπτύσσοντας το
πολυώνυμο, λαμβάνουμε άθροισμα που λέγεται ανάπτυγμα διωνύμου.
Π.χ. (x+y)2 = (x+y)(x+y) = x2 + xy+xy+y2 = x2 + 2xy + y2
Οι συντελεστές που εμφανίζονται κατά την ανάπτυξη του διωνύμου, καλούνται διωνυμικοί
συντελεστές. Στο παραπάνω παράδειγμα, για τους όρους x2 , xy και y2 προέκυψαν αντίστοιχα οι
διωνυμικοί συντελεστές 1, 2 και 1.
Το τρίγωνο του Πασκάλ είναι μία γεωμετρική διάταξη που προσφέρει (ανά γραμμή) μια
αναπαράσταση των διωνυμικών συντελεστών. Ονομάστηκε έτσι προς τιμήν του μαθηματικού
Πασκάλ στο μεγαλύτερο μέρος του δυτικού κόσμου, παρόλο που άλλοι μαθηματικοί το είχαν
μελετήσει αιώνες πριν στην Ινδία, την Περσία, την Κίνα και την Ιταλία. Οι σειρές στο τρίγωνο
του Πασκάλ αριθμούνται ξεκινώντας από την γραμμή 0. Μια απλή κατασκευή του τριγώνου
γίνεται με τον ακόλουθο τρόπο: στην σειρά 0 γράφεται μόνο ο αριθμός 1. Μετά, για την
κατασκευή των στοιχείων των επόμενων σειρών προστίθεται ο αριθμός που βρίσκεται αμέσως
από πάνω και αριστερά, με τον αριθμό αμέσως από πάνω και δεξιά. Αν οποιοσδήποτε από τους
αριθμούς δεξιά ή αριστερά δεν υπάρχει, υποκαθίσταται με μηδέν. Για παράδειγμα, ο πρώτος
αριθμός της σειράς 1 είναι 0 + 1 = 1, ενώ οι αριθμοί 1 και 3 της τρίτης σειράς προτίθενται ώστε
να δώσουν τον αριθμό 4 της τέταρτης σειράς.

Εικόνα 1: Παράδειγμα τριγώνου του Πασκάλ


Π
A. Να δημιουργήσετε ένα πρόγραμμα στη γλώσσα προγραμματισμού C, στο οποίο ζητούνται
τα εξής:
i. Να ορίσετε συνάρτηση void createPascalsTriangle(int pin[][N], int
maxrow), η οποία σε έναν ακέραιο πίνακα διαστάσεων NxN με την ονομασία pin,
εισάγει τις κατάλληλες τιμές ώστε αυτός να αναπαριστά ένα τρίγωνο του Πασκάλ που
να φτάνει μέχρι τη σειρά maxrow. Προσέξτε ότι σε κάθε γραμμή του πίνακα οι τιμές

Σελίδα 2 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

αποθηκεύονται στοιχισμένες προς τα αριστερά, όπως δείχνει το υπόδειγμα εκτέλεσης


που ακολουθεί (εικόνα 3).
ii. Να ορίσετε συνάρτηση void printPascalsTriangle(int pin[][N],int
arxi, int telos), η οποία για έναν πίνακα διαστάσεων NxN με την ονομασία pin
που αναπαριστά τρίγωνο του Πασκάλ, εμφανίζει τις σειρές του τριγώνου που οριοθετούν
οι παράμετροι arxi και telos.
iii. Να ορίσετε συνάρτηση int searchingCoefficient(int pin[][N],int
maxrow, int coef, int pinFound[]), η οποία για έναν πίνακα διαστάσεων NxN
με την ονομασία pin που αναπαριστά τρίγωνο του Πασκάλ που φτάνει μέχρι τη σειρά
maxrow, εντοπίζει τις σειρές του τριγώνου που περιέχουν τον συντελεστή coef και τις
αποθηκεύει στον πίνακα N στοιχείων pinFound. Προσέξτε ότι κάθε σειρά πρέπει να
αποθηκεύεται το πολύ μία φορά στον πίνακα pinFound. Η συνάρτηση επιστρέφει 1
όταν βρίσκει τουλάχιστον μια σειρά που περιέχει τον ζητούμενο συντελεστή, αλλιώς
επιστρέφει 0.
iv. Μια αλγεβρική παράσταση με τρεις όρους, λέγεται τριώνυμο. Π.χ. το (x+y+z) είναι
τριώνυμο. Κατ’ αναλογία, αναπαράσταση των συντελεστών που εμφανίζονται κατά την
ανάπτυξη του τριωνύμου, προσφέρει η τρισδιάστατη εκδοχή του τριγώνου του Πασκάλ,
η οποία αποκαλείται πυραμίδα του Πασκάλ ή τετράεδρο του Πασκάλ. Κάθε επίπεδό της
αναπαριστά τους συντελεστές συγκεκριμένου βαθμού. Π.χ. για το ανάπτυγμα:
(x+y+z)2 = x2 + 2xy + 2xz + y2 + 2yz + z2
το επίπεδο 2 της πυραμίδας του Πασκάλ αναπαριστά τους συντελεστές 1, 2, 2, 1, 2, 1.

Εικόνα 2: Παράδειγμα πυραμίδας του Πασκάλ


Γνωρίζοντας τους συντελεστές του τριγώνου του Πασκάλ (έστω C(i,j)), μπορούμε να
υπολογίσουμε τους συντελεστές της πυραμίδας του Πασκάλ, επιπέδου k (έστω P(k,i,j))
από την σχέση:
Σελίδα 3 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

P(k,i,j) = C(i,j) * C(k,i), όπου i = 0 έως k και j = 0 έως i.


Να ορίσετε συνάρτηση void createPascalsPyramid(int pin[][N], int
maxrow, int pin2[][N], int layer), η οποία για έναν πίνακα διαστάσεων NxN
με την ονομασία pin που αναπαριστά τρίγωνο του Πασκάλ που φτάνει μέχρι τη σειρά
maxrow, εισάγει τις κατάλληλες τιμές στον πίνακα pin2 ώστε να αναπαριστά ένα επίπεδο
layer της πυραμίδας του Πασκάλ. Η συνάρτηση επιπλέον εμφανίζει τον πίνακα pin2.
v. Να ορίσετε την συνάρτηση main() όπου θα γίνονται οι κλήσεις των προαναφερθέντων
συναρτήσεων. Η εκτέλεση του προγράμματος θα πρέπει να είναι σύμφωνη με το
υπόδειγμα εκτέλεσης του προγράμματος που ακολουθεί.
vi. Εφαρμόστε αμυντικό προγραμματισμό ώστε:
• το πλήθος των σειρών του τριγώνου του Πασκάλ να μπορεί να αναπαρασταθεί στον
δοθέντα πίνακα ptPin (κοιτάξτε σχέδιο προγράμματος),
• όταν καλείται η συνάρτηση printPascalsTriangle(), οι παράμετροι start και
end να είναι εντός των ορίων των σειρών του τριγώνου που δημιουργήθηκε.
Σημείωση: Θα πρέπει να χρησιμοποιήσετε υποχρεωτικά το σχέδιο προγράμματος με όνομα
αρχείου ypoergasia1_code_template.c.
B. Αξιοποιώντας το παραπάνω ζητούμενο πρόγραμμα, να αναπτύξετε:
i. το πολυώνυμο (x+y)9.

ii. το πολυώνυμο (α+β+γ)3.

Εικόνα 3: Υπόδειγμα εκτέλεσης του προγράμματος

Σελίδα 4 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

ΥΠΟΕΡΓΑΣΙΑ 2 (βαθμοί 25)

Ένας γράφος Γ(Κ, Α) αποτελείται από ένα σύνολο κόμβων Κ και ένα σύνολο ακμών Α. Κάθε
ακμή συνδέει δύο κόμβους που κείνται στα άκρα της ακμής. Το πλήθος των ακμών που
συνδέονται με ένα κόμβο λέγεται βαθμός του κόμβου. Στο σχήμα εικονίζεται ένας γράφος με 5
κόμβους και 5 ακμές. Οι γράφοι είναι χρήσιμοι για περιγραφή διαφόρων φαινομένων, όπως οι
“φίλοι” σε ένα κοινωνικό δίκτυο, ένα ηλεκτρικό δίκτυο, η διάδοση μιας ασθένειας, κλπ. Η
αποθήκευση ενός γράφου μπορεί να γίνει με πολλούς τρόπους. Στην εργασία αυτή ζητείται να
αποθηκεύσουμε ένα μη κατευθυνόμενο γράφο (δηλαδή ένα γράφο στον οποίο δεν ορίζεται η
φορά διαπέρασης των ακμών) με χρήση δυναμικών δομών, οι οποίες επιτρέπουν την
αποθήκευση ενός γράφου χωρίς να ορίζεται εκ των προτέρων όριο στο μέγεθος του. Θα
θεωρήσουμε ότι οι κόμβοι αριθμούνται με συνεχόμενους ακέραιους αριθμούς ξεκινώντας από
το 0. Η δομή που θα χρησιμοποιηθεί είναι η δομή δυναμικού πίνακα (πίνακας που υλοποιείται
με δείκτη και δυναμική δέσμευση μνήμης) ο οποίος θα έχει πλήθος στοιχείων όσοι οι κόμβοι
του γράφου. Κάθε στοιχείο του πίνακα θα αντιστοιχεί σε έναν κόμβο του γράφου και θα είναι
μια λίστα με τους κόμβους με τους οποίους ο κόμβος αυτός είναι συνδεδεμένος. Υποθέτουμε
ότι ένας κόμβος δεν μπορεί να έχει ακμή με τον εαυτό του. Για παράδειγμα, έστω ο γράφος 5
κόμβων του σχήματος.

1
4
0

3
2

Η αποθήκευση του γράφου αυτού θα μπορούσε να αναπαρασταθεί στην παρακάτω δομή (εικόνα
4):

0 3 1

1 2 3 0

2 3 1

3 2 1 0

Εικόνα 4: Αναπαράσταση δομής αποθήκευσης γράφου

Σελίδα 5 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

Στον παραπάνω πίνακα για να προσθέσουμε την ακμή (0,1) θα πρέπει να προσθέσουμε τον
κόμβο 1 στη λίστα του κόμβου 0 και τον κόμβο 0 στη λίστα του κόμβου 1. Η σειρά των
στοιχείων στις λίστες διασύνδεσης των κόμβων είναι τυχαία και εξαρτάται από τη σειρά των
κόμβων κατά τη διαδικασία προσθήκης στις αντίστοιχες λίστες.

Πιο συγκεκριμένα το ανωτέρω σχήμα αναπαράστασης μπορεί να υλοποιηθεί στη C με τις


ακόλουθες δηλώσεις δομών:

/* Η δομή που αναπαριστά λίστα συνδέσεων ενός κόμβου του γράφου */


typedef struct AdjListNode
{
int dest; /*κόμβος με τον οποίο υπάρχει σύνδεση */
struct AdjListNode* next; /* επόμενος */
} node;
/* δομή που περιέχει δείκτη στη λίστα συνδέσεων */
struct AdjList
{
node *head; /* δείκτης τύπου node */
};
/* Η δομή Graph περιέχει τον ακέραιο Nodes (το πλήθος των κόμβων του
γράφου) και ένα πίνακα δεικτών σε λίστες. Το μέγεθος του array αυτού
θα είναι Nodes */
struct Graph {
int Nodes;
struct AdjList* array;
};
Το πρόγραμμα που ζητείται να κατασκευαστεί έχει την εξής συμπεριφορά:

Ο χρήστης εισάγει αρχικά το πλήθος των κόμβων του γράφου:


Πρόγραμμα συνδεσιμότητας γράφου
Καταχωρίστε τον αριθμό των κόμβων του γράφου: 5
Στη συνέχεια, εμφανίζεται το εξής μενού επιλογών:
MENU
1. Προσθήκη ακμής
2. Προβολή συνδέσεων όλων των κόμβων
3. Προβολή πλήθους συνδέσεων ενός κόμβου
4. Προβολή πλήθους ακμών
5. Έξοδος
Επιλογή:

Η κάθε μια από τις επιλογές έχει την εξής συμπεριφορά:


Επιλογή 1. Προσθήκη ακμών του γράφου. Παράδειγμα διαλόγου:

Σελίδα 6 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

επιλογή:1
Πρόσθεσε ακμή μεταξύ των κόμβων 0 ως 4 (παράδειγμα: 0,4):1,3
>>> η ακμή ανάμεσα στους κόμβους 1 και 3 έχει προστεθεί

Επιλογή 2. Προβολή των διασυνδέσεων όλων των κόμβων, παράδειγμα διαλόγου:


επιλογή:2

Ο κόμβος 0 συνδέεται με: [3] [1]


Ο κόμβος 1 συνδέεται με: [2] [3] [0]
Ο κόμβος 2 συνδέεται με: [3] [1]
Ο κόμβος 3 συνδέεται με: [2] [1] [0]
Ο κόμβος 4 είναι χωρίς συνδέσεις

Επιλογή 3. Το πλήθος συνδέσεων ενός κόμβου (βαθμός του κόμβου), παράδειγμα διαλόγου:
επιλογή:3

Δώστε αριθμό κόμβου(0 έως 4) :1

>>> Το πλήθος συνδέσεων του κόμβου 1 είναι 3

Επιλογή 4. Υπολογισμός συνολικού πλήθους ακμών του γράφου, παράδειγμα διαλόγου:


επιλογή:4

>>> Το συνολικό πλήθος ακμών του γράφου είναι 5

Επιλογή 5. Έξοδος από το πρόγραμμα.

Ζητείται:

Α. Να κατασκευάσετε τη συνάρτηση δημιουργίας ενός γράφου, που υλοποιεί τον δυναμικό


πίνακα λιστών διασύνδεσης των κόμβων του γράφου. Η συνάρτηση να δηλώνεται ως struct
Graph* createGraph(int Nodes) να δέχεται ως όρισμα ένα ακέραιο που εκφράζει το
πλήθος κόμβων του γράφου και να επιστρέφει δείκτη στη δομή Graph ή NULL αν η δομή δεν
δημιουργήθηκε. Προσέξτε ότι οι κόμβοι του δημιουργηθέντα γράφου θα έχουν ονόματα από 0
μέχρι Nodes-1.

Β. Να κατασκευάσετε συνάρτηση που εισάγει μια ακμή στο γράφο. Η συνάρτηση να δηλώνεται
ως int addEdge(struct Graph* graph, int src, int dest). Η συνάρτηση να
δέχεται ως ορίσματα ένα δείκτη προς τη δομή Graph, που περιέχει το γράφο και δύο ακέραιους
αριθμούς που είναι οι δύο κόμβοι τους οποίους συνδέει η ακμή. Στη συνάρτηση να γίνεται
έλεγχος αν η ακμή υπάρχει ήδη στον γράφο, έτσι ώστε να μην πραγματοποιείται εισαγωγή ακμής
εκ νέου. Επίσης, να υλοποιηθεί αμυντικός προγραμματισμός ώστε ένας κόμβος να μην έχει ακμή
με τον εαυτό του. Η συνάρτηση να επιστρέφει 1 αν η ακμή έχει εισαχθεί και 0 αν δεν έχει
εισαχθεί επιτυχώς.

Σελίδα 7 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

Γ. Να κατασκευάσετε τη συνάρτηση void printGraph(struct Graph* graph) που


εμφανίζει τις συνδέσεις των κόμβων (επιλογή 2 του χρήστη) όπως στο παραπάνω υπόδειγμα
εκτέλεσης, δηλαδή για κάθε κόμβο εμφανίζει τη λίστα των κόμβων που συνδέονται με αυτόν. Η
συνάρτηση να δέχεται ως όρισμα ένα δείκτη προς δομή Graph, που περιέχει το γράφο.

Δ. Να κατασκευάσετε τη συνάρτηση int countEdges(struct Graph* graph, int


nodeNumber) που να υπολογίζει το πλήθος των συνδέσεων ενός κόμβου (επιλογή 3 του
χρήστη). Η συνάρτηση να δέχεται ως ορίσματα ένα δείκτη προς δομή Graph, που περιέχει το
γράφο και ένα ακέραιο που είναι ο κόμβος του οποίου αναζητούμε τις συνδέσεις. Η συνάρτηση
να επιστρέφει το πλήθος των συνδέσεων του κόμβου NodeNumber.

Ε. Να κατασκευάσετε τη συνάρτηση int countTotalEdges(struct Graph* graph)


που να υπολογίζει το συνολικό πλήθος των ακμών του γράφου (επιλογή 4 του χρήστη),
χρησιμοποιώντας τη συνάρτηση countEdges του προηγούμενου ερωτήματος.

Στο σχέδιο προγράμματος με τίτλο ypoergasia2_code_template.c καλείστε να


συμπληρώσετε τον κώδικα των συναρτήσεων που περιγράφησαν.

ΥΠΟΕΡΓΑΣΙΑ 3 (βαθμοί 25)


A. Μια ενδιαφέρουσα λειτουργία στα δυαδικά δέντρα αναζήτησης (ΔΔΑ) είναι η συγχώνευσή
τους (ή αλλιώς ένωσή τους) σε ένα νέο ενιαίο ΔΔΑ. Υπάρχουν πολλοί τρόποι υλοποίησης: η
προφανής λύση διαπέρασης των κόμβων του ενός δέντρου και κατόπιν εισαγωγή τους στο
δεύτερο δέντρο δεν είναι ικανοποιητική γιατί δεν είναι αποδοτική (απαιτεί μεγάλο πλήθος
συγκρίσεων και άρα πολύ υπολογιστικό χρόνο). Σύμφωνα με μια αναδρομική προσέγγιση, για
να συγχωνεύσουμε αποδοτικά σε ένα ΔΔΑ δύο ΔΔΑ (καλούμενα Α και Β) μπορούμε να κάνουμε
χρήση του παρακάτω αλγόριθμου:
Αλγόριθμος Merge(Δέντρο Α, Δεντρο Β)
1. Εισάγουμε τη ρίζα του Α ως ρίζα του Β (σκεφτείτε πως το δέντρο B πρέπει να
τροποποιηθεί ώστε μετά την εισαγωγή να παραμένει ΔΔΑ).
2. Κάλεσε Merge(αριστερό υποδέντρο του A, αριστερό υποδέντρο του νέου Β)
3. Κάλεσε Merge(δεξί υποδέντρο του A, δεξί υποδέντρο του νέου Β)
(όπου νέο Β αυτό που προέκυψε από το Βήμα 1 του αλγόριθμου. Να λάβετε υπόψη ότι κάθε
κόμβος οδηγεί σε μία μόνο αναδρομική κλήση, όπως φαίνεται και στο παράδειγμα που
ακολουθεί).
Παράδειγμα.
Έχουμε τα ακόλουθα ΔΔΑ:

Σελίδα 8 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

δέντρο Α δέντρο Β

7 20

6 14 9 33

31
1 10 30 3
29

Αρχικά ο κόμβος 7 εισάγεται ως ρίζα του δέντρου Β. Αυτό αναγκαστικά οδηγεί σε


τροποποιήσεις στο αριστερό υποδέντρο του Β για να διατηρηθεί ΔΔΑ: ο κόμβος 3 που είναι
μικρότερος του 7 μετακινείται αριστερά του κόμβου 7 (σχήμα 1α).
Στη συνέχεια συγχωνεύουμε το αριστερό υποδέντρο του A (κόμβοι 6 και 1, σχήμα 1β) µε το
αριστερό του νέου B, δηλαδή ουσιαστικά με τον κόμβο 3. Ο κόμβος 6 εισάγεται ως ρίζα του
κόμβου 3, και μένει μόνο ο κόμβος 1 από το αριστερό υποδέντρο του Α (σχήματα 2α, 2β). Στο
τελικό βήμα για τις συγχωνεύσεις των αριστερών υποδέντρων, ο κόμβος 1 εισάγεται ως ρίζα του
νέου υποδέντρου, δηλαδή του κόμβου 3. Και έτσι ολοκληρώνεται η διαμόρφωση του αριστερού
υποδέντρου με ρίζα τον κόμβο 7 (σχήμα 2γ).

(α) ο κόμβος 7 ως ρίζα του δέντρου Β (β) αριστερό υποδέντρο του (γ) δεξί υποδέντρο του
δέντρου Α δέντρου Α
7

3 20
6 14

9 33
1 10 30

31

29

Σχήμα 1
Τέλος, συγχωνεύουμε το δεξί υποδέντρο του Α (σχήμα 1γ) µε το δεξί του νέου Β, δηλαδή με
όλο το υποδέντρο με ρίζα τον κόμβο 20 (κόμβοι 20, 9, 33, 31, 29, σχήμα 2α). Πρώτα ο κόμβος
14 εισάγεται ως ρίζα του υποδέντρου με ρίζα τον κόμβο 20. Ο κόμβος 9, ως μικρότερος

Σελίδα 9 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

μετακινείται ως αριστερό παιδί του κόμβου 14, ενώ οι υπόλοιποι κόμβοι 33, 31 και 29
παραμένουν ως δεξί υποδέντρο του κόμβου 20 (σχήμα 3α).
Στη συνέχεια κατ’ αναλογία, το αριστερό υποδέντρο του δέντρου με ρίζα 14 (σχήμα 1γ), δηλαδή
ο κόμβος 10, θα συγχωνευθεί με το αριστερό υποδέντρο του νέου Β, που είναι ο κόμβος 9 (σχήμα
3α). Και τέλος, το δεξί υποδέντρο του δέντρου με ρίζα 14 (σχήμα 1γ), δηλαδή ο κόμβος 30, θα
συγχωνευθεί με το δεξί υποδέντρο του νέου Β, που είναι το υποδέντρο ρίζας 20 (κόμβοι 20, 33,
31, 29) (σχήμα 3α). Προκύπτει τελικά το ΔΔΑ του σχήματος 3β.

(α) ο κόμβος 6 ως ρίζα του υποδέντρου ρίζας 3 (β) αριστερό (γ) τελική διαμόρφωση του
υποδέντρο του αριστερού υποδέντρου
δέντρου Α ρίζας 7
7
(υπόλοιπο)

6 20 7

3 9 33
1 6

31 1

29 3

Σχήμα 2

(α) 14 ως ρίζα του υποδέντρου 20 (β) το τελικό ενιαίο ΔΔΑ

14
7
9 20
14
6
33
10 30
1
31 33
9 20
3
29 31
29

Σχήμα 3

Δίνονται τα εξής ΔΔΑ:

Σελίδα 10 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

δέντρο Α δέντρο Β

10
12

3 20
6 21

14
2 16

17 18

19

Να συγχωνεύσετε τα δυο ΔΔΑ, ακολουθώντας την προαναφερθείσα αναδρομική προσέγγιση.


Να δείξετε όλα τα ενδιάμεσα βήματα.
B. Δίνεται το εξής δυαδικό δέντρο:

9 7

8 12 17 13

19 10 16 21 20

i. Εξετάστε αν το δέντρο αυτό είναι δέντρο-σωρός ελαχίστων.


• Αν είναι, αιτιολογήστε την απάντησή σας.
• Αν δεν είναι, εξετάστε αν υπάρχει ένας και μόνος κόμβος που αλλάζοντας την
τιμή του τότε το δέντρο γίνεται δέντρο-σωρός ελαχίστων. Ποιος κόμβος είναι
αυτός και ποιες οι πιθανές τιμές του, εάν όλες οι τιμές των κόμβων είναι
διαφορετικά στοιχεία μεταξύ τους και μόνο ακέραιες;
ii. Εισάγετε τα δεδομένα των κόμβων του δέντρου του σχήματος με τη σειρά που
συναντώνται κατά την μεταδιατεταγμένη διαπέρασή του σε ένα άλλο, αρχικά κενό,
δέντρο-σωρό μεγίστων. Να δείξετε το δέντρο-σωρό μεγίστων που σχηματίζεται μετά
την εισαγωγή των στοιχείων 21, 20, 5.
iii. Στο τελικό δέντρο-σωρό μεγίστων που προκύπτει μετά την εισαγωγή όλων των
δεδομένων του υποερωτήματος ii, να γίνει διαγραφή της ρίζας. Δώστε το τελικό

Σελίδα 11 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

δέντρο-σωρό μεγίστων που προκύπτει από τη διαγραφή αυτή, μαζί με μία σύντομη
αιτιολόγηση για το πώς αυτό προέκυψε.
iv. Κατασκευάστε ένα δυαδικό δέντρο αναζήτησης, εισάγοντας τα στοιχεία του δέντρου-
σωρού μεγίστων που προέκυψε μετά τη διαγραφή ρίζας (στο σκέλος iii), με τη σειρά
που συναντώνται κατά την ενδοδιατεταγμένη διαπέρασή του.

ΥΠΟΕΡΓΑΣΙΑ 4 (βαθμοί 25)


Αντικείμενο της συγκεκριμένης άσκησης είναι η διερεύνηση των δυνατοτήτων της C για
αναπαράσταση αραιών πινάκων δύο διαστάσεων. Αραιός καλείται ένας πίνακας του οποίου η
συντριπτική πλειονότητα των στοιχείων είναι μηδενικά. Για παράδειγμα, ο πιο κάτω πίνακας Α
διαστάσεων 410 είναι αραιός αφού από τα 40 συνολικά στοιχεία του μόνο τα 4 είναι μη
μηδενικά.

0 3 0 0 0 0 0 0 0 4
0 0 0 0 0 0 7 0 0 0
A= 0 0 0 0 0 0 0 0 0 0
0 0 0 0 8 0 0 0 0 0

Στην περίπτωση αραιών πινάκων είναι προτιμότερο από άποψη χώρου μνήμης να
αποθηκεύονται και να εκτελούνται πράξεις μόνο με τα μη-μηδενικά στοιχεία τέτοιων πινάκων
και να παραλείπεται η αποθήκευση των μηδενικών στοιχείων. Ένας αραιός πίνακας μπορεί να
αναπαρασταθεί είτε με πολλαπλές λίστες (Βοηθητικό Υλικό (study.eap.gr)- Τόμος Γ-
Εργαστηριακές Ασκήσεις σε Δομές Δεδομένων με τη Γλώσσα C, Άσκηση 2.2, όπου και
περιγράφεται η διαδικασία μετατροπής παραδοσιακού δισδιάστατου πίνακα σε πολλαπλές
λίστες) είτε με μία λίστα που είναι και η προσέγγιση που θα ακολουθήσουμε στην άσκηση αυτή.
Πιο συγκεκριμένα μία εναλλακτική μέθοδος αποθήκευσης ενός αραιού πίνακα στη μνήμη του
υπολογιστή είναι μέσω της χρήσης μίας απλά συνδεδεμένης λίστας, όπου κάθε μη μηδενικό
στοιχείο του πίνακα στη γραμμή i και στη στήλη j, αντιστοιχίζεται σε ένα κόμβο της. Κάθε
κόμβος περιέχει τον αριθμό της γραμμής και της στήλης στην οποία είναι αποθηκευμένο το
αντίστοιχο στοιχείο καθώς και την τιμή του. Τα στοιχεία στη λίστα εμφανίζονται σε σειρά
προσπέλασης του πίνακα ανά γραμμές (από αριστερά προς τα δεξιά και από πάνω προς τα
κάτω). Για παράδειγμα ο πίνακας Α θα αναπαρασταθεί με την ακόλουθη λίστα:

head 0 1 3 0 9 4 1 6 7 3 4 8 NULL

Σελίδα 12 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

Είναι επίσης χρήσιμο, για να είναι εύκολη η επιβεβαίωση της εγκυρότητας πράξεων όπως ο
πολλαπλασιασμός πινάκων, να αποθηκεύεται πέρα από τη λίστα των μη μηδενικών στοιχείων
και το πλήθος των γραμμών και των στηλών του πίνακα.
Ας δούμε τώρα πως θα υλοποιηθούν τα όσα αναφέραμε στη γλώσσα C. Κάθε κόμβος της λίστας
θα έχει την πιο κάτω δομή node, η οποία έχει ως πεδία τρεις αριθμούς και ένα δείκτη σε ένα
κόμβο τύπου node. Το πρώτο πεδίο (row) αποθηκεύει τον αριθμό γραμμής, το δεύτερο πεδίο
(column) αποθηκεύει τον αριθμό της στήλης και το τρίτο πεδίο (value) αποθηκεύει την τιμή του
στοιχείου του πίνακα.
typedef struct node /* Κόμβος αποθήκευσης μη μηδενικού στοιχείου του
πίνακα */
{
int row; /* Γραμμή του στοιχείου */
int column; /* Στήλη του στοιχείου */
float value /* Τιμή του στοιχείου */
struct node * next; /* Επόμενο στοιχείο */
} node;
Κάθε πίνακας θα αναπαρίσταται από μία δομή τύπου table με τρία πεδία. To πρώτο πεδίο (head)
θα είναι δείκτης στην κεφαλή της λίστας που περιέχει τα μη μηδενικά στοιχεία του πίνακα το
δεύτερο πεδίο (number_of_rows) θα αποθηκεύει το πλήθος των γραμμών του πίνακα και το
τρίτο πεδίο (number_of_columns) θα αποθηκεύει το πλήθος των στηλών του πίνακα.
typedef struct table /* Δομή αναπαράστασης πίνακα */
{
node * head; /* Κεφαλή λίστας μη μηδενικών στοιχείων */
int number_of_rows; /* Πλήθος γραμμών */
int number_of_columns; /* Πλήθος στηλών */
} table;
Ζητείται να υλοποιήσετε συναρτήσεις που διαβάζουν τα στοιχεία ενός αραιού πίνακα, και
πολλαπλασιάζουν δύο αραιούς πίνακες που αναπαρίστανται σαν απλές συνδεδεμένες λίστες.
Πιο συγκεκριμένα ζητούνται τα εξής:
Α. Να ορίσετε συνάρτηση με όνομα void Entertable(table * input) που να ζητεί από
τον χρήστη τα στοιχεία ενός αραιού πίνακα που προσπελαύνεται μέσω ενός δείκτη με όνομα
input. Η συνάρτηση να ζητάει αρχικά να δοθεί το πλήθος των γραμμών και των στηλών, και
μετά να ζητάει τα μη μηδενικά στοιχεία του πίνακα ένα ένα ρωτώντας μετά από κάθε επανάληψη
τον χρήστη αν θέλει να συνεχίσει και να δώσει και άλλο στοιχείο. Πραγματοποιήστε αμυντικό
προγραμματισμό για να εγγυηθείτε ότι το πλήθος των γραμμών και στηλών είναι μεγαλύτερο
του μηδενός, ότι τα στοιχεία δίνονται ανά γραμμές (από αριστερά προς τα δεξιά και από πάνω
Σελίδα 13 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

προς τα κάτω) και ότι η γραμμή και η στήλη που δίνεται για τη θέση τους, δεν βγαίνει εκτός
ορίων πλήθους γραμμών και στηλών του πίνακα. Επίσης πρέπει να ελέγχετε ότι τα στοιχεία που
δίνονται είναι μη μηδενικά.
Β. Να ορίσετε μια συνάρτηση με όνομα void Multables(table table1, table
table2, table * table3) η οποία να παίρνει ως όρισμα δύο αραιούς πίνακες table1 και
table2, και να επιστρέφει το γινόμενο των δύο πινάκων μέσω ενός δείκτη σε πίνακα table3.
Υπενθυμίζεται (Τόμος Β- σελίδα 142-δραστηριότητα 6.4) ότι τo γινόμενο δύο πινάκων table1
διαστάσεων ΜxΝ και table2 διαστάσεων ΝxΤ είναι ένας νέος πίνακας διαστάσεων ΜxΤ όπου
το στοιχείο του στη γραμμή i και στήλη j προκύπτει αθροίζοντας τα γινόμενα κάθε στοιχείου
της γραμμής i του table1 με το αντίστοιχο στοιχείο της στήλης j του table2. Αν το πλήθος
στηλών του πίνακα table1 δεν είναι ίσο με το πλήθος γραμμών του πίνακα table2 τότε ο
πολλαπλασιασμός δεν ορίζεται. H συνάρτηση πρέπει να ελέγχει αν ο πολλαπλασιασμός ορίζεται
και αν όχι να επιστρέφει, αφήνοντας τον πίνακα στον οποίο δείχνει το όρισμα table3
αμετάβλητο. Επισημαίνεται ότι σε μερικές περιπτώσεις το αποτέλεσμα του πολλαπλασιασμού
δύο αραιών πινάκων μπορεί να μην είναι αραιό, όμως για τους σκοπούς της συνάρτησής μας
ζητάμε σε κάθε περίπτωση να επιστρέψουμε την αναπαράσταση του πίνακα αποτέλεσμα ως
λίστα.

Στο σχέδιο προγράμματος με τίτλο ypoergasia4_code_template.c καλείστε να


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

Γενικές Υποδείξεις:
I) Για τις απαντήσεις της εργασίας μπορείτε να ανατρέξετε στην συμπληρωματική
βιβλιογραφία που δίνεται και στα βοηθητικά κείμενα που υπάρχουν στον δικτυακό τόπο /
portal της θεματικής ενότητας. Συνιστάται να προσθέσετε στο τέλος της εργασίας σας
κατάλογο βιβλιογραφίας.
II) Τρόπος παράδοσης εργασίας:
Οι απαντήσεις πρέπει να είναι γραμμένες με χρήση επεξεργαστή κειμένου (π.χ. Word) σε
σελίδες διαστάσεων Α4. Το αρχείο να περιέχει ως πρώτη σελίδα το κείμενο του Εντύπου
Υποβολής - Αξιολόγησης και ως δεύτερη σελίδα τον τίτλο «Σχόλια προς τον φοιτητή» (θα
συμπληρωθεί από τον καθηγητή σας). Οι απαντήσεις στις υπο-εργασίες θα αρχίζουν από
την τρίτη σελίδα, χωρίς να επαναλαμβάνονται οι εκφωνήσεις. Κάθε υπο-εργασία θα αρχίζει
από νέα σελίδα. Για την απάντησή σας θα πρέπει να χρησιμοποιείτε υποχρεωτικά το

Σελίδα 14 από 15
4η ΓΡΑΠΤΗ ΕΡΓΑΣΙΑ ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2019-2020

Πρότυπο Υποβολής Γραπτής Εργασίας. Ενδεικτικά, οι άριστες απαντήσεις μπορούν να


επιτευχθούν σε περίπου 18 σελίδες.
III) Η καλή παρουσίαση της εργασίας λαμβάνεται υπόψη στην αξιολόγηση της εργασίας.
IV) Αμυντικός προγραμματισμός και σχολιασμός κώδικα:
Ο κώδικας πρέπει να είναι επαρκώς σχολιασμένος και να χρησιμοποιεί στοιχεία αμυντικού
προγραμματισμού, όπου αυτό ζητείται. Για την εφαρμογή του αμυντικού προγραμματισμού
αρκεί να γίνεται έλεγχος ως προς το εάν μία τιμή που εισάγεται από το χρήστη του
προγράμματος βρίσκεται εντός αποδεκτών ορίων (π.χ. να είναι θετική, διαφορετική από το
0, μεγαλύτερη από 20 κ.λπ.). Δεν απαιτείται έλεγχος ως προς το εάν η τιμή ανήκει στο
σωστό τύπο δεδομένων (π.χ. ακέραιος, πραγματικός αριθμός, χαρακτήρας κ.λπ.) σύμφωνα
με τον τύπο της μεταβλητής στην οποία θα αποθηκευτεί η τιμή αυτή.
V) Τρόπος παράδοσης κώδικα:
Στα ερωτήματα όπου ζητείται υλοποίηση κώδικα σε γλώσσα C, και στο έγγραφο της
απάντησής σας και στο αρχείο του κώδικα θα πρέπει να δίνεται ολόκληρο το πρόγραμμα,
επισημαίνοντας με σχόλια πού απαντάτε κάθε ερώτημα. Για να θεωρούνται οι απαντήσεις
ολοκληρωμένες θα πρέπει:
Στα ερωτήματα που ζητείται υλοποίηση κώδικα στη γλώσσα προγραμματισμού C (ANSI
C), για να θεωρηθούν οι απαντήσεις σας ολοκληρωμένες θα πρέπει:
• Ο κώδικας (όπου ζητείται) να είναι επαρκώς σχολιασμένος και ενσωματωμένος μέσα
στο .doc αρχείο του Word με τις απαντήσεις σας καθώς και σε ξεχωριστό .c αρχείο
κειμένου, όχι Word.
• Το όνομα κάθε .c αρχείου να περιλαμβάνει το επώνυμό σας με λατινικούς χαρακτήρες, το
χαρακτήρα της υπογράμμισης και τον αριθμό του συγκεκριμένου υποερωτήματος (π.χ. αν
το επώνυμό σας είναι Γεωργίου, τότε ο κώδικας για την υποεργασία 1β θα έχει το όνομα
Georgiou_1b.c).Κάθε αρχείο C που θα παραδοθεί θα πρέπει τουλάχιστον να περνάει τη
φάση της μεταγλώττισης χωρίς λάθη.

• Όλα τα .c αρχεία με τον πηγαίο κώδικα και το .doc αρχείο κειμένου να υποβληθούν στη
διεύθυνση http://study.eap.gr.

Σελίδα 15 από 15

You might also like