630 likes | 744 Views
Πινακες (Arrays). Σημασια Συνταξη Αρχικοποιηση Προσβαση Παραμετροι Αριθμητικη Δεικτων και Πινακες. Δομες Δεδομενων. Πίνακες αποτελούν ένα σημαντικό δομημένο τύπο δεδομένων (structured data type) ή απλά μία δομή δεδομένων (data structure)
E N D
Πινακες (Arrays) • Σημασια • Συνταξη • Αρχικοποιηση • Προσβαση • Παραμετροι • Αριθμητικη Δεικτων και Πινακες
Δομες Δεδομενων • Πίνακες αποτελούν ένα σημαντικό δομημένο τύπο δεδομένων (structured data type) ή απλά μία δομή δεδομένων (data structure) • Μία δομή δεδομένων είναι ενα συνολο συγγενών δεδομένων τα οποία αποθηκεύονται κάτω από το ίδιο όνομα • language defined vs user defined
31 md[0] md[1] md[2] … … md[11 28 τιμες 31 τυπος Μεγεθος πληθος στοιχειων ονομα (διευθ.) 31 Πινακας • Ένας πίνακας είναι μία δομή δεδομένων, όπου ένα σύνολο αντικειμένων του ιδίου τύπου αποθηκεύονται σε σειρά, π.χ. int md[12] = {31,28,31,30,31,30, 31,31,30,31,30,31};
Σημασια • Οπως μεταβλητη: • τυπο, ονομα, τιμη (τιμες),και μεγεθος (πληθος στοιχειων) • Aποθηκευση και αναγνωση δεδομενων • Τα στοιχεια σε ενα πινακα μεν στοιχεία αναφερονται ως στοιχείο 0, στοιχείο 1, στοιχείο 2, …, και στοιχείο (n-1). Πχ στο md το στοιχειο 0 εχει τιμη 31, το στοιχειο 1 τιμη 28 κτλ
Αποθηκευση Πινακα • Τα στοιχεία ενός πίνακα αποθηκεύονται σε συνεχόμενα κελια στη μνήμη του υπολογιστή. • Πινακες συνηθως εχουν γρηγορη προσβαση και προτιμουνται απο αλλες δομες (οταν υπαρχει επιλογη).
Συνταξη <τυπος> ονομα[<μεγεθος>]; <τυπος> ονομα[<μεγεθος>]={αρχικοποιηση}; • Το μεγεθος χρειαζεται, εκτος και εαν γινεται αρχικοποιση. • Ορισμος χωρις μεγεθος • το μεγεθος του πινακα ειναι ισο με τα στοιχεια της αρχικοποιηση char pinakas[]={‘a’, ‘b’, ‘c’};
Προσβαση Πινακα • Συνταξη:oνομα[δεικτης] • Ο δεικτης πινακα(subscript) πρεπει να ειναι int • x[0]τιμη πρώτου στοιχείου του πίνακα x • x[i] τιμηi-οστού (ith +1) στοιχείου του πίνακα x • Ευθύνη προγραμματιστή να επαληθεύσει ότι η τιμή δεικτη πινακα είναι στο πεδίο [0, πλήθος_στοιχείων 1]
Πινακας σαν παραμετρος • int pinakas[100000]; • pinakas περιεχει την διευθυνση του πινακα • Κληση με παραμετρο πινακα • παιρνουμε διευθυνση του πινακα foo(pinakas); • Ορισμος Συναρτησης με παραμετρο πινακα • void foo(int t[]); • Πλευρικο φαινομενο αλλαγες στον πινακα
Επεξεργασια ανα στοιχειο int x[]={1,2,3,5,7,11,13,17,19,23,29,31}; printf(%d, x[0]); x[3] = 8258; sum = x[0] + x[1]; sum += x[2]; x[3] += 1; x[2] = x[0] + x[1];
Αναφορά σε Στοιχεία του Πίνακα x[i] = 0; x[i] = x[j]; x[j+k*4]= x[u] + 3; x[x[i]]= p; diff = x[y]-x[foo()]; total += x[i++]; (x[i]== x[(int)f])
Αρχικοποιηση Πίνακα #define MAX 100 /*αρχικοποιηση στοιχειων του πινακα x σε 0*/ int x[MAX], i; for(i=0;i<MAX;++i) x[i]=0;
Αρχικοποιηση Πίνακα #define MAX 100 void init_table(int x[], int size){ int i; for(i=0;i<size;++i) x[i]=0; } int main() { int table[MAX]; init_table(table,MAX); …. }
Αρχικοποιηση Πίνακα #define SIZE 5 int square[SIZE], i; /*αρχικοποιηση:στοιχειο i se i^2*/ for (i = 0; i < SIZE; ++i) square[i] = i * i; 0 1 2 3 4
Παραλληλοι Πινακες #define STUDENT_NUM 55 int studend_id[STUDENT_NUM]; float student_grade[STUDENT_NUM]; • int student_id[i] περιεχει αρ. ταυτοτητας και float student_grade[i] τον βαθμο του φοιτητη με ταυτοτητα student_id[i] • πινακες (συνηθως) με ιδιο αριθμο στοιχειων για συγγενεις πληροφοριες
Παραλληλοι Πινακες student_id student_grade 0 0 12345 2.12 1 1 37349 6.14 2 2 9995 4.56 ... ... 20001 54 7.8 54
Παραλληλοι Πινακες void display_id_grade(int table_id[],float table_grade[], int size) { int j; for(j=0;j<size;++j) printf(“Student with id: %d, grade: %f\n”, table_id[j],table_grade[j]); }
Παραλληλοι Πινακες • Eναλλακτικα ενας πινακας με εγγραφες (structures κεφ. 11) student_grade student_id 0 12345 2.12 1 37349 6.14 2 9995 4.56 ... 20001 7.8 54
Γραμμικη αναζητηση(Linear Search) • Γραψετε τμημα προγραμματος που αναζητα μεσα στον πινακα ακεραιων στοιχειων student_id την θεση που περιεχει την τιμη τηςz*. Το μεγεθος του πινακα οριζεται με την σταθερα STUDENT_NUM. H μεταβλητη i θα πρεπει να περιεχει την θεση που περιεχει την τιμη z, αν δεν βρεθει την τιμη STUDENT_NUM(* υποθεση για 1η τιμη)
Γραμμικη αναζητηση(Linear Search) • Τι πρεπει να γινει; Αναζητηση • Για καθε στοιχειο του πινακα • εαν ειναι ισο με z • φυλαξε θεση • τερματισε επαναληψη • εξεταση (στην χειροτερη περιπτωση) ολων των στοιχειων του πινακα (αναλογο με διαβασμα μιας σειρας μεγεθους STUDENT_NUM)
int i; for(i=0;i<STUDENT_NUM;++i) if (student_id[i]==z){ break; } /* εαν i<STUDENT_NUM βρεθηκε */
Γραμμικη αναζητηση(με συναρτηση) • Γραψετε συναρτηση που αναζητα μεσα στον πινακα ακεραιων στοιχειων id_table τον αριθμο ταυτοτητας id. Το μεγεθος του πινακα περιεχεται στην παραμετρο size (δηλαδη αριθμος φοιτητων στον πινακα). Eαν βρεθει η ταυτοτητα να επιστραφει η θεση που την περιεχει, αλλιως να επιστραφει η τιμη του size.
Γραμμικη αναζητηση(με συναρτηση) • Γραψετε συναρτηση που αναζητα μεσα στον πινακα ακεραιων στοιχειων id_table την τιμη της μεταβλητης id. Το μεγεθος του πινακα περιεχεται στην παραμετρο size. Να επιστραφει η θεση που περιεχει την τιμη id. Αν δεν βρεθει επιστρεψετε την τιμη size.
int location_of_student(int id_table[], int size, int id) { int i; for(i=0;i<size;++i) if (student_id[i]==id) return i; return size; /* break and return i ok */ }
int location_of_item(int id_table[], int size, int id) { int i; for(i=0; i<size && id_table[i]!=id ; ++i); return i; }
Aναζητηση και Ενημερωση • Υποθεστε υπαρξη δυο παραλληλων πινακων με ιδιο μεγεθος (οπως πιο πανω, ταυτοτητες και βαθμοι). • Γραψετε συναρτηση που αναζητα μεσα στον πινακα ακεραιων στοιχειων id_table τον φοιτητη με αριθμο ταυτοτητας id και ενημερωνει τον βαθμο του φοιτητη με την τιμη της παραμετρου new_grade στον (παραλληλο) πινακα grade_table . Το μεγεθος των πινακων περιεχεται στην παραμετρο size (δηλαδη αριθμος φοιτητων). Eαν δεν βρεθει η ταυτοτητα επιστραφεται η τιμη -1 αλλιως εαν η ενημερωσης ειναι επιτυχης επιστρεφεται 0. • Μπορειται να χρησιμοποιησετε την συναρτηση location_of_item (οπως πιο πανω) χωρις να την ορισετε.
int update_grade(int id_table[], float grade_table[], int size, int id, float new_grade) { int location = location_of_student(id_table,size,id); if (location == size) return -1; else{ grade_table[location]= new_grade; return 0; } }
int update_grade(int id_table[], float grade_table[], int size, int id, float new_grade) { int location = location_of_student(id_table,size,id); if (location == size) return -1; else{ assert(location>=size); grade_table[location]= new_grade; return 1; } }
int get_student_grade(int id_table[], float grade_table[], int size, int id) { int location = location_of_student(id_table,size,id); if (location == size) return -1; else{ assert(location>=size); return grade_table[location]; } }
Μετρηση(με συναρτηση) • Γραψετε συναρτηση που υπολογιζει και επιστρεφει των αριθμων φοιτητων (α) που παιρνουν βαθμο απο 8 και πανω και (β) που παιρνουν βαθμο μικροτερο απο το 5. Οι βαθμοι ειναι αποθηκευμενοι σε πινακα.Το μεγεθος του πινακα περιεχεται στην παραμετρο size.
void grade_count(const int grade_table[], int size, int *above_eight, int *below_five) { int i; *above_eight = *below_five = 0; for(i=0;i<size;++i) if (grade_table[i]>=8.0) ++*above_eight; else if (grade_table[i]<5) ++*below_five; }
const (σταθερα) • Συνταξη: const τυπος ονομα • Σημασια: δηλώνεται ότι δεν μπορει να γινει αναθεση στην μεταβλητη (read only) • Λογική του προγραμματος και ασφαλεια • Ιδιαιτερα χρησιμη για παραμετρους • Πχ στο grade_count απαγορεύει την τροποποιήση των περιεχομένων του grade_table
Δυαδικη Αναζητηση(Binary Search) • Χρησιμη εαν τα στοιχεία του πίνακα είναι ταξινομημένα (πχ αύξουσα ή φθινουσα σειρά)
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 max pos min Aναζητηση 91
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 max pos min Aναζητηση 91
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 max pos min Aναζητηση 91
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 max pos min Aναζητηση 4
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 max pos min Aναζητηση 4
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 max pos min Aναζητηση 4
4 0 6 1 7 5 2 3 61 3 111 35 88 -23 91 71 min max Aναζητηση 4
int binary_search(const int table[], int size, int item) { int Min = 0, Max = size – 1, pos= Min + Max) / 2; while(Min <= Max){ if (item > table[pos]) Min = pos + 1; else if (item< table[pos]) Max = pos – 1; else /* item found!!! */ return pos; pos = (Min + Max) / 2; } return -1; }
Ταξινόμηση Φυσαλίδας (Bubble Sort) • Ενόσω ο πίνακας δεν είναι ταξινομημένος • διαδοχικά σύγκρινε γειτoνικα στοιχεία του πίνακα και ενάλλαξε τα περιεχόμενά τους εάν δεν είναι στη ζητούμενη σειρά • Ο αλγόριθμος συνεπάγεται διπλή επανάληψη (nested)
3 1 3 0 4 1 2 1 4 0 2 2 0 1 4 3 3 0 4 1 2 2 4 3 0 25 25 35 111 111 25 -40 -40 3 3 111 25 35 3 3 35 111 35 3 111 -40 35 -40 -40 25
3 1 3 0 4 1 2 1 4 0 2 2 0 1 4 3 3 0 4 1 2 2 4 3 0 25 25 35 -40 -40 25 35 111 3 3 -40 25 35 25 3 35 35 -40 3 111 111 -40 111 111 3
3 1 3 0 4 1 2 1 4 0 2 2 0 1 4 3 3 0 4 1 2 2 4 3 0 25 -40 -40 35 35 -40 35 111 3 3 35 -40 -40 25 3 25 35 25 3 111 111 25 111 111 3
3 1 3 0 4 1 2 1 4 0 2 2 0 1 4 3 3 0 4 1 2 2 4 3 0 3 3 25 35 35 3 35 111 -40 -40 35 3 25 -40 -40 25 35 25 -40 111 111 25 111 111 3
2 1 4 2 1 4 2 0 0 1 1 0 3 0 2 2 4 3 4 3 0 3 3 4 1 35 -40 3 3 25 3 -40 25 111 35 35 111 25 3 -40 -40 3 111 25 -40 35 111 35 111 25 Tαξινομημενο!
Παρατηρησεις Bubble Sort) • Kαθε προσπελαση καθοριζει την θεση τουλαχιστο ενος στοιχειου. • 1η το μεγιστο στιοχειο • 2η το αμεσως επομενο μεγαλυτερο • κτλ • Μετα απο καθε προσπελαση μειωση αριθμων στοιχειων που εξεταζονται κατα ενα • Εαν σε μια προσπελαση δεν γινει εναλαγη: sorted!
3 1 3 0 4 1 2 1 4 0 2 2 0 1 4 3 3 0 4 1 2 2 4 3 0 25 25 35 111 111 25 -40 -40 3 3 111 25 35 3 3 35 111 35 3 111 -40 35 -40 -40 25
3 4 3 1 0 0 3 1 2 4 2 1 2 4 3 0 1 2 4 0 -40 25 3 111 -40 3 35 35 25 35 -40 3 25 -40 25 111 35 111 111 3
3 4 0 4 1 2 2 3 4 1 0 1 0 2 3 25 -40 111 35 3 25 3 111 -40 -40 111 25 35 35 3