Date post: | 30-Dec-2015 |
Category: |
Documents |
Upload: | jeanine-sheehan |
View: | 36 times |
Download: | 2 times |
Πινακες (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
31
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
/*αρχικοποιηση στοιχειων του πινακα 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
12
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]
• πινακες (συνηθως) με ιδιο αριθμο στοιχειων για συγγενεις πληροφοριες
Παραλληλοι Πινακες
0
12
...
54
12345
37349
9995
20001
0
12
...
54
2.12
6.14
4.56
7.8
student_id student_grade
Παραλληλοι Πινακες
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)
0
12
...
54
12345
37349
9995
20001
2.12
6.14
4.56
7.8
student_id student_grade
Γραμμικη αναζητηση(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)
• Χρησιμη εαν τα στοιχεία του πίνακα είναι ταξινομημένα (πχ αύξουσα ή φθινουσα σειρά)
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
min maxpos
Aναζητηση 91
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
min maxpos
Aναζητηση 91
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
min maxpos
Aναζητηση 91
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
min maxpos
Aναζητηση 4
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
min maxpos
Aναζητηση 4
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
min maxpos
Aναζητηση 4
-23
0
3
1
111
7
35
2
71
4
61
3
88
5
91
6
minmax
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)
25
0
3
1
35
2
-40
4
111
3
3
0
25
1
35
2
-40
4
111
3
3
0
25
1
35
2
-40
4
111
3
3
0
25
1
35
2
-40
4
111
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
-40
2
111
4
35
3
3
0
25
1
-40
2
111
4
35
3
3
0
25
1
-40
2
111
4
35
3
3
0
25
1
-40
2
111
4
35
3
3
0
-40
1
25
2
111
4
35
3
3
0
-40
1
25
2
111
4
35
3
3
0
-40
1
25
2
111
4
35
3
3
0
-40
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
Tαξινομημενο!
Παρατηρησεις Bubble Sort)• Kαθε προσπελαση καθοριζει την θεση
τουλαχιστο ενος στοιχειου.– 1η το μεγιστο στιοχειο– 2η το αμεσως επομενο μεγαλυτερο– κτλ
• Μετα απο καθε προσπελαση μειωση αριθμων στοιχειων που εξεταζονται κατα ενα
• Εαν σε μια προσπελαση δεν γινει εναλαγη: sorted!
25
0
3
1
35
2
-40
4
111
3
3
0
25
1
35
2
-40
4
111
3
3
0
25
1
35
2
-40
4
111
3
3
0
25
1
35
2
-40
4
111
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
35
2
111
4
-40
3
3
0
25
1
-40
2
111
4
35
3
3
0
25
1
-40
2
111
4
35
3
3
0
25
1
-40
2
111
4
35
3
3
0
-40
1
25
2
111
4
35
3
3
0
-40
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
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);
display_table(table,SIZE);
}
Ταξινόμηση Επιλογής(Selection Sort)
• ν = μ = μεγεθος του πινακα
• Eπανελαβε ν-1 φορες– βρες την θεση με το πιο μεγαλο στοιχειο στα μ
πρωτα στοιχεια του πινακα– αλλαξε την τιμη του πιο πανω στοιχειου με την
τιμη στην θεση μ-1– μ = μ - 1
25
0
3
1
35
2
-40
4
111
3
25
0
3
1
35
2
111
4
-40
3
25
0
3
1
-40
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
-40
0
3
1
25
2
111
4
35
3
1η
2η
3η
4η
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 ιδιο με &t[0]– *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]);
}
}