Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Σχετικά έγγραφα
Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

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

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

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

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

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ. Ασκήσεις Επανάληψης

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Α' Περιόδου Θέµα 1. (α') 2 - ii 3 - iii 4 - iv

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

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

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

Περιεχόμενα. Πρόλογος... 21

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 3 Ο. Σταθερές-Παράμετροι-Μεταβλητές Αριθμητικοί & Λογικοί Τελεστές Δομή ελέγχου-επιλογής Σύνθετοι έλεγχοι

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #5

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

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

Δομημένος Προγραμματισμός

Δομημένος Προγραμματισμός (ΤΛ1006)

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

Η γλώσσα προγραμματισμού C

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

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

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Η γλώσσα προγραμματισμού C

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

Πληροφορική & Τηλεπικοινωνίες Υλοποίηση Συστημάτων Βάσεων Δεδομένων - Χειμερινό Εξάμηνο Καθηγητής Δ. Γουνόπουλος

Εισαγωγή στον Προγραμματισμό

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

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

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

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

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

Μεθόδων Επίλυσης Προβλημάτων

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

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

Στόχοι και αντικείμενο ενότητας. Πέρασμα Πίνακα σε Συνάρτηση (συν.) Πέρασμα Πίνακα σε Συνάρτηση. #8.. Ειδικά Θέματα Αλγορίθμων

Εισαγωγή στον Προγραμματισμό (με. τη C)

Η γλώσσα προγραμματισμού C

Εισαγωγή στον Προγραµµατισµό. Πανεπιστήµιο Θεσσαλίας Τµήµα Ηλεκτρολόγων Μηχανικών και Μηχανικών Η/Υ

Ηλεκτρονικοί Υπολογιστές

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

Ανάπτυξη και Σχεδίαση Λογισμικού

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

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

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Ενδεικτική περιγραφή μαθήματος

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

Δομημένος Προγραμματισμός (ΤΛ1006)

Οι εντολές ελέγχου της ροής ενός προγράμματος.

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Ανάπτυξη και Σχεδίαση Λογισμικού

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

Προχωρημένες έννοιες προγραμματισμού σε C

Κεφάλαιο ΙV: Δείκτες και πίνακες. 4.1 Δείκτες.

ΑΡ Χ Ε Ι Α Κ Ε Ι Μ Ε Ν Ο Υ (text files)

Η γλώσσα προγραμματισμού C

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

Περιεχόμενα. Πρόλογος... 17

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

Δομημένος Προγραμματισμός (ΤΛ1006)

Πληροφορική & Τηλεπικοινωνίες. K18 - Υλοποίηση Συστημάτων Βάσεων Δεδομένων Εαρινό Εξάμηνο

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 7 Ο. Αριθμητικές πράξεις Τυχαίοι αριθμοί Εφαρμογές σε προβλήματα ΣΙΝΑΤΚΑΣ Ι. ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Μεθόδων Επίλυσης Προβλημάτων

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ. Ερωτήσεις Επανάληψης

Ανάπτυξη και Σχεδίαση Λογισμικού

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Κεφάλαιο 4: Συνθήκες Έλεγχου (if-else, switch) και Λογικοί τελεστές / παραστάσεις. (Διάλεξη 8)

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

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

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

Βήματα: μνήμη 2. Αλγόριθμος βήματα που περιγράφουν την επεξεργασία των δεδομένων. Δομές Δεδομένων + Αλγόριθμοι = Προγράμματα

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Επανάληψη για τις Τελικές εξετάσεις. (Διάλεξη 24) ΕΠΛ 032: ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

Δομημένος Προγραμματισμός (ΤΛ1006)

Εισαγωγή στον Προγραμματισμό

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

Εισαγωγή στον Προγραμματισμό

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ ΕΞΕΤΑΣΗ IOYNIOY 2018 ΘΕΜΑΤΑ Α ΟΝΟΜΑΤΕΠΩΝΥΜΟ:... ΑΕΜ: ΕΞΑΜΗΝΟ:

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Διάλεξη 11η: Δείκτες, μέρος 1

Απλά Προγράμματα. Βήματα: 1. Καθορισμός παράστασης δεδομένων στη μνήμη 2. Αλγόριθμος βήματα που περιγράφουν την επεξεργασία των δεδομένων

ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

lab13grades 449 PASS 451 PASS PASS FAIL 1900 FAIL Page 1

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Η εντολή if-else. Η απλή μορφή της εντολής if είναι η ακόλουθη: if (συνθήκη) { Η γενική μορφή της εντολής ifelse. εντολή_1; εντολή_2;..

Transcript:

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Εργαστήριο 9η σειρά ασκήσεων (μέρος 2). Κοζάνη, 14 Δεκεμβρίου 2007. Κάθε πρόγραμμα εξαρτάται από αλγόριθμους και δομές δεδομένων, αλλά μόνο λίγα απαιτούν κάποια καινοτομία ως προς αυτά τα δύο. Ακόμη και σε ένα πολύπλοκο πρόγραμμα, οι περισσότερες δομές δεδομένων θα είναι πίνακες, λίστες, δέντρα ή πίνακες κατακερματισμού (hash tables). Όποτε χρειάζεται κάτι πολύπλοκο, πιθανότατα θα βασίζεται σε απλούστερα γνωστά στοιχεία. Όπως υπάρχουν λίγες θεμελιώδεις δομές δεδομένων, έτσι υπάρχουν λίγα θεμελιώδη προβλήματα σχετικά με αυτές και λίγες μέθοδοι για τη λύση αυτών των προβλημάτων. Τα κυριότερα, θεμελιωδέστερα και συχνότερα προβλήματα είναι η ταξινόμηση και η αναζήτηση σε ένα σύνολο δεδομένων. Τα επόμενα προγράμματα παρουσιάζουν τις κυριότερες μεθόδους ταξινόμησης 1. Η ταξινόμηση είναι απαραίτητη για την ευχερέστερη και ταχύτερη αναζήτηση μέσα από ένα σύνολο δεδομένων. Με τις μεθόδους αναζήτησης θα ασχοληθούμε την επόμενη φορά. Πρόγραμμα p9-2-1 Μέθοδος Ταχείας Ταξινόμησης (quick sort) Δημιουργήστε ένα project, ονομάστε το p9 και δημιουργήστε τα παρακάτω αρχεία που θα ανήκουν σε αυτό: α) Ένα αρχείο με το όνομα p9main.c και τα ακόλουθα περιεχόμενα (με γαλάζιο οι γραμμές που δίνονται ήδη από το περιβάλλον ανάπτυξης και με κόκκινο αυτές που θα προσθέσουμε): #include <stdlib.h> #define NDAT 10 int main(char argc, char *argv[]) { int i, unsorted[ndat], sorted[ndat]; for (i = 0; i < NDAT; i++) unsorted[i] = sorted[i] = (int) (NDAT * (float) rand() / (float) RAND_MAX); sortmethod(); sort(sorted, NDAT); printf("\n\tno\tunsorted\tsorted\n"); for(i = 0; i < NDAT; i++) 1 Το υποπρόγραμμα quick_sort που υλοποιεί την αντίστοιχη μέθοδο βασίστηκε σε σχετικό παράδειγμα από την εξής πηγή: Β. Σεφερίδης, C για αρχάριους, εκδόσεις Κλειδάριθμος, Αθήνα 1995. 8 1 / 7

printf("\t%d\t %d\t\t %d\n", i, unsorted[i], sorted[i]); printf("finished!\n"); system("pause"); return 0; Στο πρόγραμμα αυτό δημιουργούμε δύο ακέραιους πίνακες διάστασης NDAT = 10 (το NDAT ορίστηκε πιο πάνω ως συμβολική σταθερά με την οδηγία #define). Σε αυτούς δίνουμε σε κάθε στοιχείο την ίδια (τυχαία) τιμή που θα είναι ένας τυχαίος ακέραιος αριθμός από 0 έως NDAT-1. Αρχικά λοιπόν τα περιεχόμενα των δύο πινάκων ταυτίζονται. Μετά, ο ένας από τους δύο, με το όνομα sorted, θα υποστεί την επεξεργασία μιας συνάρτησης που υλοποιεί κάποιον αλγόριθμο ταξινόμησης μετά από την οποία, τα περιεχόμενά του θα έχουν τοποθετηθεί κατ' αύξουσα σειρά. Τα στοιχεία των πινάκων τυπώνονται στη συνέχεια, στην ίδια σειρά για κάθε αριθμοδείκτη. β) Ένα αρχείο με το όνομα p9lib.c και τα ακόλουθα περιεχόμενα: void sortmethod( void ) { int method; printf("\npick a method: \n"); printf("1 = quick sort\n"); scanf("%d", &method); switch(method) { case 1: sort = quick_sort; default: printf("\nwrong option!"); sort = do_nothing; /* to avoid segmentation fault */ void do_nothing( int *a, int n ) { void swap( int *x, int *y ) { int t; t = *x; *x = *y; *y = t; 8 2 / 7

void quick_sort(int *a, int n) { int i, j, middle; i = 0; j = n - 1; middle = a[j/2]; do { while(a[i] < middle) i++; while(a[j] > middle) j--; if(i < j) swap(a+i, a+j); else if(i > j) i++; j--; while(i <= j); if(j > 0) quick_sort(a, j+1); if(i < n-1) quick_sort(a+i, n-i); Σε αυτό το αρχείο ορίζεται πρώτα η συνάρτηση sortmethod η οποία καλείται και στο κύριο πρόγραμμα. Αυτή ορίζει ότι το sort που είναι δείκτης σε συνάρτηση θα δείχνει σε μία συνάρτηση που διαλέγουμε μεταξύ αυτών που μας προτείνει. Προς το παρόν προτείνει μόνο μία. Αν δώσουμε αριθμό που δεν αντιστοιχεί σε προτεινόμενη επιλογή, τότε θα δείχνει στη συνάρτηση do_nothing που, όπως μαρτυρεί και το όνομά της, δεν κάνει τίποτε, ενώ τυπώνεται και ένα μήνυμα λάθους. Σε αυτό το αρχείο υπάρχει επίσης και η συνάρτηση swap για την ανταλλαγή των τιμών δύο μεταβλητών (η μία παίρνει την τιμή της άλλης) που παίζει βοηθητικό ρόλο στην ταξινόμηση όπως αυτή υλοποιείται αμέσως παρακάτω. Τέλος, υπάρχει η συνάρτηση που υλοποιεί την πρώτη μέθοδο που εξετάζουμε, τη μέθοδο ταχείας ταξινόμησης. Η συγκεκριμένη υλοποίηση είναι αναδρομική. Οι αναδρομικές κλήσεις της συνάρτησης υποδεικνύονται με έντονα γράμματα. γ) Ένα αρχείο επικεφαλίδας με το όνομα p9lib.h και τα ακόλουθα περιεχόμενα: #ifndef P9LIB_H #define P9LIB_H void (*sort)(); void sortmethod( void ); void do_nothing( int *, int ); void swap( int *, int * ); void quick_sort(int *, int ); #endif Εδώ απλά δηλώνεται ο δείκτης σε συνάρτηση sort, καθώς και οι συναρτήσεις που ορίσαμε πιο πάνω. Μεταγλωττίστε και εκτελέστε. 8 3 / 7

Άσκηση p9-2-2 Συνάρτηση ταχείας ταξινόμησης πρότυπης βιβλιοθήκης (standard library qsort) Η επίδοση ενός αλγόριθμου μπορεί να επηρεαστεί από τη συγκεκριμένη μορφή των δεδομένων εισόδου. Η παραπάνω υλοποίηση της ταχείας ταξινόμησης γενικά δουλεύει καλά, είναι όμως δυνατό να γίνει πολύ αργή αν π.χ. το μεσαίο στοιχείο κάθε τμήματος χωρίζει αυτό σε μία πολύ μικρή και μία πολύ μεγάλη περιοχή. Τότε θα γίνουν πολλές αναδρομικές κλήσεις με κίνδυνο, μάλιστα, υπερχείλισης της στοίβας του υπολογιστή. Ευτυχώς υπάρχουν και άλλοι τρόποι υλοποίησης που αποφεύγουν τα προβλήματα αυτών των ειδικών περιπτώσεων. Η μέθοδος ταχείας ταξινόμησης υπάρχει και σαν συνάρτηση της πρότυπης βιβλιοθήκης με το όνομα qsort, δηλωμένη στο αρχείο επικεφαλίδας <stdlib.h> και θα την προσθέσουμε σαν τελευταία επιλογή για το πρόγραμμά μας. Η συνάρτηση qsort παίρνει ως παραμέτρους εισόδου τον πίνακα (ως δείκτη τύπου void για να είναι γενικής χρήσης) και τον αριθμό των στοιχείων του, το πλάτος σε bytes του τύπου των στοιχείων (double, int, char,...), και ένα δείκτη σε μία ακέραια συνάρτηση η οποία έχει σκοπό να συγκρίνει δύο αριθμούς. Αυτή η συνάρτηση, έστω compare το όνομά της, δε δίνεται έτοιμη αλλά πρέπει να οριστεί από τον προγραμματιστή έτσι ώστε να παίρνει για είσοδο δύο δείκτες τύπου const void και να επιστρέφει 1, 0 ή -1 ανάλογα με το αν η πρώτη παράμετρος είναι μεγαλύτερη, ίση ή μικρότερη από τη δεύτερη. Σημείωση: const είναι μία δήλωση που λέει ότι κάποια μεταβλητή... δεν πρέπει να μεταβληθεί στη διάρκεια του προγράμματος! Αυτό μας προφυλάσσει από το να αλλάξουμε την τιμή της κατά λάθος σε κάποιο σημείο του προγράμματος ενώ δεν πρέπει. Οι δείκτες τύπου void είναι δείκτες γενικής χρήσης και μπορούμε να τους χρησιμοποιούμε π.χ. για να περνάμε ορίσματα διαφόρων τύπων σε μία συνάρτηση. Βάσει των παραπάνω, αλλά και για να μπορέσουμε να διατηρήσουμε τη δομή του προγράμματός μας, θα ορίσουμε μία συνάρτηση την οποία θα δείχνει η sort, με ίδιο πρωτότυπο (τύπο και λίστα παραμέτρων εισόδου) με τις προηγούμενες η οποία θα καλεί την qsort. Επίσης, θα ορίσουμε μία συνάρτηση για τη σύγκριση δύο ακέραιων, αλλά με το πρωτότυπο που απαιτεί η qsort. Στο αρχείο επικεφαλίδας κάνουμε τις προσθήκες που φαίνονται με κόκκινο χρώμα, ανάμεσα από την τελευταία προηγούμενη δήλωση και το #endif: #ifndef P9LIB_H #define P9LIB_H void (*sort)(); void sortmethod( void ); void do_nothing( int *, int ); void quick_sort(int *, int ); void standard_qsort(int *, int ); int compare(const void *, const void * ); #endif Η συνάρτηση standard_qsort θα καλεί τη συνάρτηση βιβλιοθήκης qsort ενώ η compare θα συγκρίνει δύο ακέραιους αριθμούς με τον τρόπο που θα δούμε αμέσως. Στο αρχείο p9lib.c πρέπει πρώτα να προσθέσουμε το αρχείο <stdlib.h> για να μπορέσουμε να κάνουμε χρήση της qsort: #include <stdlib.h> Μετά, προσθέτουμε τον κώδικα για τη συμπλήρωση του μενού επιλογών:... printf("\npick a method: \n"); 8 4 / 7

printf("1 = quick sort\n"); printf("2 = standard library qsort\n"); scanf("%d", &method); switch(method) { case 1: sort = quick_sort; case 2: sort = standard_qsort; default: printf("\nwrong option!"); sort = do_nothing; /* to avoid segmentation fault */... Τέλος, προσθέτουμε την υλοποίηση των συναρτήσεων που αναφέραμε: void standard_qsort(int *a, int n) { qsort(a, n, sizeof(a[0]), compare); int compare(const void *xx, const void *yy) { int value; int *x, *y; x = (int *) xx; y = (int *) yy; if(*x > *y) value = 1; else if (*x == *y) value = 0; else value = -1; return(value); Η συνάρτηση standard_qsort είναι πολύ απλή γιατί το μόνο που κάνει είναι να καλεί την qsort με τα κατάλληλα ορίσματα. Παρατηρείστε ότι το όνομα της συνάρτησης compare χρησιμεύει ως δείκτης σε αυτή. Η συνάρτηση compare παίρνει δύο δείκτες τύπου void και αποδίδει τις τιμές όπου δείχνουν σε δύο δείκτες τύπου int με τη βοήθεια καταλληλης μετατροπής τύπου που υποδηλώνεται από το (int *). Άσκηση p9-2-3 Επιδόσεις αλγόριθμων ταξινόμησης Για να διαπιστώσουμε την αποδοτικότητα ενός αλγόριθμου στην πράξη είναι χρήσιμο να 8 5 / 7

χρονομετρήσουμε την ολοκλήρωσή του για διάφορα δεδομένα εισόδου. Στο κύριο πρόγραμμα κάνουμε τις εξής αλλαγές: Εισάγουμε ένα ακόμη αρχείο επικεφαλίδας για να χρησιμοποιήσουμε συναρτήσεις μέτρησης του χρόνου: #include <stdlib.h> #include <time.h> Εισάγουμε την εξής δήλωση μεταβλητής (με κόκκινο): int i, unsorted[ndat], sorted[ndat]; clock_t t; Εισάγουμε δύο εντολές για τον προσδιορισμό της χρονικής στιγμής έναρξης της ταξινόμησης και της διάρκειας αυτής, πριν και μετά από την κλήση της sort, ως εξής: sortmethod(); t = clock(); sort(sorted, NDAT); t = clock() - t; Τροποποιούμε το υπόλοιπο τμήμα που αφορά την εκτύπωση αποτελεσμάτων προσθέτοντας την εμφάνιση της διάρκειας ταξινόμησης και περικλείοντας την εμφάνιση των ταξινομημένων δεδομένων σε μια δομή if για να εκτυπώνονται προαιρετικά, ως εξής: printf("\ndata sorted within %lf sec", (double) t / (double) CLOCKS_PER_SEC); printf("\ndisplay results? 1 for yes "); scanf("%d", &i); if(i == 1) { printf("\n\tno\tunsorted\tsorted\n"); for(i = 0; i < NDAT; i++) printf("\t%d\t %d\t\t %d\n", i, unsorted[i], sorted[i]); printf("finished!\n"); Αλλάζοντας τις τιμές του NDAT (π.χ. 1000000), εκτελέστε το πρόγραμμα για τις δύο επιλογές και συγκρίνετε τις υλοποιήσεις της μεθόδου ταχείας ταξινόμησης ως προς την ταχύτητά τους. Άσκηση p9-2-4 Η μέθοδος δυαδικής αναζήτησης: συνάρτηση βιβλιοθήκης bsearch Εφόσον έχουμε ταξινομήσει τα δεδομένα μας είναι εύκολο να αναζητήσουμε σε αυτά το στοιχείο που μας ενδιαφέρει. Διακρίνουμε δύο κύριες μεθόδους: τη γραμμμική αναζήτηση (δηλαδή τον έλεγχο κάθε στοιχείου στη σειρά μέχρι να βρούμε αυτό που θέλουμε) και τη δυαδική αναζήτηση. Η πρώτη είναι γενική με την έννοια ότι εφαρμόζεται ακόμη και όταν τα δεδομένα είναι αταξινόμητα αλλά είναι αργή, με πολυπλοκότητα Ο(Ν). Η δεύτερη απαιτεί ταξινομημένα στοιχεία αλλά είναι πολύ γρηγορότερη. Βασίζεται στη σύγκριση του κλειδιού αναζήτησης με το μεσαίο στοιχείο του διαστήματος τιμών και αντικατάσταση αυτού του διαστήματος από το μισό όπου βρίσκεται το ζητούμενο στοιχείο. 8 6 / 7

Στη συνέχεια προσθέτουμε στο πρόγραμμα μία λειτουργία δυαδικής αναζήτησης βασισμένη στη συνάρτηση βιβλιοθήκης bsearch, που καλείται με τρόπο παρόμοιο με αυτόν που είδαμε σχετικά με την qsearch. Η συνάρτηση bsearch, δηλωμένη στο αρχείο stdlib.h, παίρνει ως παραμέτρους εισόδου ένα δείκτη στο κλειδί αναζήτησης, τον πίνακα δεδομένων και τον αριθμό των στοιχείων του, το πλάτος σε bytes του τύπου των στοιχείων (double, int, char,...), και ένα δείκτη σε μία ακέραια συνάρτηση η οποία έχει σκοπό να συγκρίνει δύο αριθμούς. Αυτή η συνάρτηση δε θα είναι άλλη από την compare που ορίσαμε πιο πριν και χρησιμοποιήσαμε στην qsort. Θέλουμε να βρούμε αν ένας αριθμός που δίνουμε από το πληκτρολόγιο υπάρχει στον ταξινομημένο πίνακα. Η bsearch μας επιστρέφει ένα δείκτη (τύπου void, δηλαδή δείκτη μπαλαντέρ ) στην περιοχή μνήμης όπου βρίσκεται το στοιχείο του οποίου το κλειδί αναζητούμε. Αν αυτός ο δείκτης είναι NULL τότε το στοιχείο δε βρέθηκε στον πίνακα. Προσθέτουμε μία νέα δήλωση στις δηλώσεις μεταβλητών στην αρχή του προγράμματος: int *found; Μετά, στο τέλος του προγράμματος, πριν από την printf("finished!\n"); προσθέτουμε τον ακόλουθο κώδικα: printf("\nnumber between 0 and NDAT to find: "); scanf("%d", &i); found = (int *) bsearch(&i, sorted, NDAT, sizeof(int), compare); if(found == NULL) printf("\n%d not found!\n", i); else printf("\n%d has been found!\n", i); Μεταγλωττίστε και εκτελέστε Ερώτηση: Εδώ τα στοιχεία είναι πολύ απλά (στοιχεία ακέραιου πίνακα) και ταυτίζονται με το κλειδί οπότε η bsearch μπορεί να μας πει μόνο αν υπάρχουν (δεν έχει νόημα να μας πει την τιμή τους που ήδη δώσαμε). Με λίγο προγραμματισμό ακόμη όμως, ίσως μπορούμε να χρησιμοποιήσουμε την τιμή που μας επιστρέφει η bsearch για να βεβαιωθούμε και για τη θέση του αριθμού μέσα στον πίνακα. Πώς μπορεί να γίνει αυτό; 8 7 / 7