Πινακες (Arrays) Σημασια Συνταξη Αρχικοποιηση Προσβαση Παραμετροι Αριθμητικη Δεικτων και Πινακες
Δομες Δεδομενων Πίνακες αποτελούν ένα σημαντικό δομημένο τύπο δεδομένων (structured data type) ή απλά μία δομή δεδομένων (data structure) Μία δομή δεδομένων είναι ενα συνολο συγγενών δεδομένων τα οποία αποθηκεύονται κάτω από το ίδιο όνομα language defined vs user defined
Πινακας Ένας πίνακας είναι μία δομή δεδομένων, όπου ένα σύνολο αντικειμένων του ιδίου τύπου αποθηκεύονται σε σειρά, π.χ. int md[12] = {31,28,31,30,31,30, 31,31,30,31,30,31}; τυπος Μεγεθος πληθος στοιχειων ονομα (διευθ.) md[0] md[1] md[2] … md[11 31 28 τιμες
Σημασια Οπως μεταβλητη: τυπο, ονομα, τιμη (τιμες), και μεγεθος (πληθος στοιχειων) 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 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); ….
Αρχικοποιηση Πίνακα /*αρχικοποιηση:στοιχειο i se i^2*/ #define SIZE 5 int square[SIZE], i; /*αρχικοποιηση:στοιχειο i se i^2*/ for (i = 0; i < SIZE; ++i) square[i] = i * i; 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] πινακες (συνηθως) με ιδιο αριθμο στοιχειων για συγγενεις πληροφοριες
Παραλληλοι Πινακες 1 1 2 2 ... ... 54 54 student_id student_grade 12345 2.12 1 37349 1 6.14 2 2 9995 4.56 ... ... 54 20001 54 7.8
Παραλληλοι Πινακες 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_id student_grade 12345 2.12 1 37349 6.14 2 9995 4.56 ... 54 20001 7.8
Γραμμικη αναζητηση(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 */ }
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) Χρησιμη εαν τα στοιχεία του πίνακα είναι ταξινομημένα (πχ αύξουσα ή φθινουσα σειρά)
Aναζητηση 91 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 min max pos
Aναζητηση 91 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 min pos max
Aναζητηση 91 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 min pos max
Aναζητηση 4 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 min max pos
Aναζητηση 4 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 min pos max
Aναζητηση 4 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 min pos max
Aναζητηση 4 -23 3 1 35 2 61 3 71 4 88 5 91 6 111 7 max min
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)
25 3 1 35 2 -40 4 111 3 25 1 35 2 -40 4 111 3 25 1 35 2 -40 4 111 3 25 1 35 2 -40 4 111 3 25 1 35 2 111 4 -40
3 25 1 35 2 111 4 -40 3 25 1 35 2 111 4 -40 3 25 1 35 2 111 4 -40 3 25 1 -40 2 111 4 35 3 25 1 -40 2 111 4 35
3 25 1 -40 2 111 4 35 3 25 1 -40 2 111 4 35 3 -40 1 25 2 111 4 35 3 -40 1 25 2 111 4 35 3 -40 1 25 2 111 4 35
3 -40 1 25 2 111 4 35 -40 3 1 25 2 111 4 35 -40 3 1 25 2 111 4 35 -40 3 1 25 2 111 4 35 -40 3 1 25 2 111 4 35
-40 3 1 25 2 111 4 35 -40 3 1 25 2 111 4 35 -40 3 1 25 2 111 4 35 Tαξινομημενο! -40 3 1 25 2 111 4 35 -40 3 1 25 2 111 4 35
Παρατηρησεις Bubble Sort) Kαθε προσπελαση καθοριζει την θεση τουλαχιστο ενος στοιχειου. 1η το μεγιστο στιοχειο 2η το αμεσως επομενο μεγαλυτερο κτλ Μετα απο καθε προσπελαση μειωση αριθμων στοιχειων που εξεταζονται κατα ενα Εαν σε μια προσπελαση δεν γινει εναλαγη: sorted!
25 3 1 35 2 -40 4 111 3 25 1 35 2 -40 4 111 3 25 1 35 2 -40 4 111 3 25 1 35 2 -40 4 111 3 25 1 35 2 111 4 -40
3 25 1 35 2 111 4 -40 3 25 1 35 2 111 4 -40 3 25 1 35 2 111 4 -40 3 25 1 -40 2 111 4 35
3 25 1 -40 2 111 4 35 3 25 1 -40 2 111 4 35 3 -40 1 25 2 111 4 35
3 -40 1 25 2 111 4 35 -40 3 1 25 2 111 4 35
-40 3 1 25 2 111 4 35 Tαξινομημενο!
void bubble_sort(int table[], int size) { int Sorted, len = size – 1, k; do{ Sorted = 1; /*υπόθεση πίνακας ταξινομημένος */ for (k = 0; k < len; k++) if (table[k]<table[k+1]){ swap(&table[k],&table[k+1]); Sorted = 0; } len; } while (!Sorted && len > 0);
void bubble_sort(int compare(int,int) , int table[], int size) { int Sorted, len = size – 1, k; do{ Sorted = 1; /*υπόθεση πίνακας ταξινομημένος */ for (k = 0; k < len; k++) if (compare(table[k],table[k+1])){ swap(&table[k],&table[k+1]); Sorted = 0; } len; } while (!Sorted && len > 0); σχεση (φθινουσα, αυξουσα)
int less(int x, int y) { return x < y; } int greater(int x, int y) { return x > y; } #define SIZE 5 int main () { int table[SIZE] = {9,3,5,1,7}; bubble_sort(less, table, 5); display_table(table,SIZE); bubble_sort(greater, table,5); }
Ταξινόμηση Επιλογής(Selection Sort) ν = μ = μεγεθος του πινακα Eπανελαβε ν-1 φορες βρες την θεση με το πιο μεγαλο στοιχειο στα μ πρωτα στοιχεια του πινακα αλλαξε την τιμη του πιο πανω στοιχειου με την τιμη στην θεση μ-1 μ = μ - 1
25 3 1 35 2 -40 4 111 1η 25 3 1 35 2 111 4 -40 2η 25 3 1 -40 2 111 4 35 3η -40 3 1 25 2 111 4 35 4η -40 3 1 25 2 111 4 35
selection_sort(int table[], int size) { int max_location, len; void selection_sort(int table[], int size) { int max_location, len; for (len = size; len > 1; len){ max_location = get_location_max(table, len); swap(&table[len 1], &table[max_location]); } int get_location_max(int *table, int size){ int i,max_position=0; for(i=1;i<size;++i) if (*(table+i) > *(table+max_position) ) max_position = i; return max_position; }
Δεικτες και Πινακες Ονομα πινακα, t, ειναι διευθυνση στοιχειου t[0] Γενικα: *(t+i) ιδιο με t[i] και t+i ιδιο με &t[i] ++t αυξανει το t κατα το μεγεθος του τυπου που δειχνει το t (πχ εαν int *t κατα sizeof(int)) δειχνει στο ‘‘επομενο’’ στοιχειο
int get_location_max(int *table, int size){ int i,max_position=0; for(i=1;i<size;++i) if (table[i] > table[max_position] ) max_position = i; return max_position; } void display_table(int *table, int size){ int i; for(i=1;i<size;++i, ++table) printf(“%d %d\n”,i, table); }
Δεικτες και Πινακες Προσοχη: δεικτης μπορει να παρει νεα τιμη, πινακας οχι!!! int t[10], i = 5, *p; p = t; p[2] = 3; ++p; *p = 14; scanf(“%d”,&p[i+4]); *(t+i) = 33; ++t;
Δεικτες και Πινακες Προσοχη: δεικτης μπορει να παρει νεα τιμη, πινακας οχι!!! int t[10], i = 5, *p; p = t; /* p = &t[0] */ p[2] = 3; /* αναθεσε στην t[2] την τιμη 3*/ ++p; /* p points to t[1] */ *p = 14; /* αναθεσε στην t[1] την τιμη 14*/ scanf(“%d”,&p[i+4]); /* t[10] */ *(t+i) = 33; /* αναθεσε στην t[4] την τιμη 33 */ ++t; /* ΔΕΝ ΕΠΙΤΡΕΠΕΤΑΙ */
void selection_sort(int table[], int size) { int max_location, len; for (len = size; len > 1; len){ max_location = get_location_max(table, len); swap(&table[len 1], &table[max_location]); } void selection_sort(int table[], int size) { int max_location, len; for (len = size; len > 1; len){ max_location = get_location_max(table, len); swap(table+len 1, table+max_location); }