Προγραμματισμός Ι Δομές Δεδομένων Δημήτρης Μιχαήλ Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο Ακ. Έτος 2009-2010
Δομές Δεδομένων Μια δομή δεδομένων είναι μια συλλογή δεδομένων με κάποιες ιδιότητες η οποία προσφέρει εύκολη πρόσβαση σε αυτά τα δεδομένα. Έχουμε δει ως τώρα μια στατική δομή δεδομένων, τον πίνακα. Τι κάνουμε όμως στην περίπτωση που θέλουμε να αποθηκεύουμε ένα συνεχώς μεταβαλλόμενο αριθμό από δεδομένα; Χαροκόπειο Πανεπιστήμιο 2/29
Δυναμικές Δομές Δεδομένων Είναι δομές δεδομένων που μπορούν να αυξομειώνουν το μέγεθος τους, δηλαδή να αναπτύσσονται και να συρρικνώνονται στον χρόνο εκτέλεσης. Η C ως γλώσσα προγραμματισμού δεν παρέχει τέτοιες δομές. Μας παρέχει όμως τα απαραίτητα εργαλεία για να φτιάξουμε τέτοιες δομές δεδομένων. Χαροκόπειο Πανεπιστήμιο 3/29
Απαραίτητα Εργαλεία.1. structs - δομές.2. δυναμική καταχώρηση μνήμης - malloc, free.3. δείκτες - pointers.4. μετονομασία τύπων - typedef Για να φτιάξουμε δυναμικές δομές δεδομένων χρειάζεται να χρησιμοποιήσουμε τα πιο σημαντικά και συχνά πιο δυσκολονόητα κομμάτια της γλώσσας. Χαροκόπειο Πανεπιστήμιο 4/29
Διάφορες Δομές Δεδομένων Θα δούμε δύο από τις πιο σημαντικές δομές δεδομένων.1. συνδεδεμένες λίστες.2. στοίβες Ανάλογα με τις ανάγκες της εφαρμογής χρησιμοποιούμε διαφορετική δομή. Χαροκόπειο Πανεπιστήμιο 5/29
Αυτοαναφερόμενες Δομές Η C μας παρέχει την δυνατότητα να φτιάξουμε δομές (structs) οι οποίες αυτοαναφέρονται: struct node { int data ; struct node * next ; } ; Η δομή node περιέχει έναν ακέραιο και ένα δείκτη τύπου node. Χαροκόπειο Πανεπιστήμιο 6/29
Αυτοαναφερόμενες Δομές Ουσιαστικά η C μας επιτρέπει να δηλώσουμε μια μεταβλητή δείκτη σε τύπο που δεν έχει οριστεί ακόμη. Για παράδειγμα το παρακάτω πρόγραμμα είναι απόλυτα σωστό. #include < s t d i o. h> int main ( ) { struct node * ptr ; } Προσέξτε πως στο παραπάνω πρόγραμμα δεν δηλώνουμε ποτέ την δομή node. Χαροκόπειο Πανεπιστήμιο 7/29
Συνδεδεμένη Λίστα Μια γραμμική συλλογή αυτοαναφερόμενων δομών, που ονομάζονται κόμβοι, και συνδέονται από συνδέσεις δεικτών. NULL Μια συνδεδεμένη λίστα προσπελαύνεται μέσω ενός δείκτη στον πρώτο κόμβο της λίστας. Κατά σύμβαση, ο δείκτης σύνδεσης στον τελευταίο κόμβο της λίστας τίθεται σε NULL για να σηματοδοτήσει το τέλος της λίστας. Χαροκόπειο Πανεπιστήμιο 8/29
Συνδεδεμένη Λίστα Η πληροφορία σε κάθε κόμβο μπορεί να είναι οποιαδήποτε τύπου, ακόμη και struct. NULL Χαροκόπειο Πανεπιστήμιο 9/29
Συνδεδεμένη Λίστα Κόμβος typedef struct { int AM ; char student [ 5 0 ] ; } student_data ; struct node { student_data data ; struct node * next ; } ; Ένας κόμβος λίστας που περιέχει πληροφορίες για έναν φοιτητή. Χαροκόπειο Πανεπιστήμιο 10/29
Υλοποίηση Λίστας 1 #include < s t d i o. h> 2 #include < s t d l i b. h> 3 #include < assert. h> 4 5 / / data type 6 typedef struct 7 { 8 int AM ; 9 } datat ; 10 11 / / node d e f i n i t i o n 12 typedef struct noder * node ; 13 14 struct noder 15 { 16 datat data ; 17 node next ; 18 } ; Χαροκόπειο Πανεπιστήμιο 11/29
Υλοποίηση Λίστας 19 20 / / l i s t d e f i n i t i o n 21 typedef struct listr * list ; 22 23 struct listr 24 { 25 node head ; 26 int size ; 27 } ; 28 29 / / create l i s t 30 list list_create ( ) 31 { 32 list l = ( list ) malloc ( sizeof ( struct listr ) ) ; 33 assert ( l ) ; 34 l >head = NULL ; 35 l >size = 0; 36 return l ; 37 } Χαροκόπειο Πανεπιστήμιο 12/29
Υλοποίηση Λίστας 38 / / create node 39 node list_newnode ( datat data ) 40 { 41 node n = ( node ) malloc ( sizeof ( struct noder ) ) ; 42 assert ( n ) ; 43 n >data = data ; 44 n >next = NULL ; 45 return n ; 46 } 47 48 / / f r e e node memory 49 void list_freenode ( node n ) 50 { 51 assert ( n ) ; 52 free ( n ) ; 53 } Χαροκόπειο Πανεπιστήμιο 13/29
Υλοποίηση Λίστας 54 / / get f i r s t l i s t node 55 node list_first ( list l ) 56 { 57 assert ( l ) ; 58 return l >head ; 59 } 60 61 / / get next l i s t node 62 node list_next ( node n ) 63 { 64 assert ( n ) ; 65 return n >next ; 66 } 67 68 / / get node data 69 datat list_data ( node n ) 70 { 71 assert ( n ) ; 72 return n >data ; 73 } Χαροκόπειο Πανεπιστήμιο 14/29
Υλοποίηση Λίστας 74 / / check i f l i s t i s empty 75 int list_empty ( list l ) 76 { 77 assert ( l ) ; 78 return l >head == NULL ; 79 } 80 81 / / get l i s t size 82 int list_size ( list l ) 83 { 84 assert ( l ) ; 85 return l >size ; 86 } Χαροκόπειο Πανεπιστήμιο 15/29
Υλοποίηση Λίστας 87 / / i n s e r t as f i r s t node i n l i s t 88 void list_insertfirst ( list l, node n ) 89 { 90 assert ( l && n ) ; 91 n >next = l >head ; 92 l >head = n ; 93 l >size++; 94 } 95 96 / / d e l e t e f i r s t node i n l i s t 97 node list_deletefirst ( list l ) 98 { 99 assert ( l && l >head ) ; 100 101 node ret = l >head ; 102 l >head = l >head >next ; 103 l >size ; 104 ret >next = NULL ; 105 return ret ; 106 } Χαροκόπειο Πανεπιστήμιο 16/29
Υλοποίηση Λίστας 107 / / i n s e r t a f t e r node i n l i s t 108 void list_insertafter ( list l, node after, node n ) 109 { 110 assert ( l && after && n ) ; 111 n >next = after >next ; 112 after >next = n ; 113 l >size++; 114 } 115 116 / / d e l e t e a node a f t e r a node 117 node list_deleteafter ( list l, node prev ) 118 { 119 assert ( l && prev && prev >next ) ; 120 node ret = prev >next ; 121 prev >next = ret >next ; 122 ret >next = NULL ; 123 return ret ; 124 } Χαροκόπειο Πανεπιστήμιο 17/29
Υλοποίηση Λίστας 125 / / destroy l i s t and f r e e memory 126 void list_destroy ( list l ) 127 { 128 while (! list_empty ( l ) ) 129 list_freenode ( list_deletefirst ( l ) ) ; 130 131 free ( l ) ; 132 } Χαροκόπειο Πανεπιστήμιο 18/29
Υλοποίηση Λίστας 133 int main ( ) 134 { 135 int am ; 136 datat data ; 137 node n ; 138 list l = list_create ( ) ; 139 140 do { 141 printf ( "Give a student AM (-1 to quit): " ) ; 142 scanf ( "%d", &am ) ; 143 144 if ( am >= 0 ) { 145 data. AM = am ; 146 list_insertfirst ( l, list_newnode ( data ) ) ; 147 } 148 } while ( am >= 0 ) ; 149 150 for ( n = list_first ( l ) ; n! = NULL ; n = list_next ( n ) ) 151 printf ( "%d ", list_data ( n ). AM ) ; 152 printf ( "\n" ) ; 153 154 list_destroy ( l ) ; 155 return 0; 156 } Χαροκόπειο Πανεπιστήμιο 19/29
Στοίβα Η στοίβα είναι μια δυναμική δομή δεδομένων όπου μπορούμε να έχουμε πρόσβαση μόνο στο τελευταίο στοιχείο που εισήχθει (την λεγόμενη κορυφή της στοίβας). Push Pop Χαροκόπειο Πανεπιστήμιο 20/29
Λειτουργίες Στοίβας Push Pop Μια στοίβα παρέχει τις λειτουργίες PUSH( S, x ) Προσθέτει ένα στοιχείο x στην στοίβα S. POP( S ) Διαγράφει το νεότερο στοιχείο που βρίσκεται στην στοίβα S. TOP( S ) Επιστρέφει το νεότερο στοιχείο που βρίσκεται στην στοίβα S. Χαροκόπειο Πανεπιστήμιο 21/29
Υλοποίηση Στοίβας Μπορούμε να υλοποιήσουμε μια στοίβα με την ίδια τεχνική που χρησιμοποιήσαμε για την λίστα. Χαροκόπειο Πανεπιστήμιο 22/29
Υλοποίηση Στοίβας 1 #include < s t d i o. h> 2 #include < s t d l i b. h> 3 #include < assert. h> 4 5 / / data type 6 typedef struct 7 { 8 char c ; 9 } datat ; 10 11 / / node d e f i n i t i o n 12 typedef struct noder * node ; 13 14 struct noder 15 { 16 datat data ; 17 node next ; 18 } ; Χαροκόπειο Πανεπιστήμιο 23/29
Υλοποίηση Στοίβας 19 20 / / stack d e f i n i t i o n 21 typedef struct stackr * stack ; 22 23 struct stackr 24 { 25 node head ; 26 int size ; 27 } ; 28 29 / / create stack 30 stack stack_create ( ) 31 { 32 stack s = ( stack ) malloc ( sizeof ( struct stackr ) ) ; 33 assert ( s ) ; 34 s >head = NULL ; 35 s >size = 0; 36 return s ; 37 } Χαροκόπειο Πανεπιστήμιο 24/29
Υλοποίηση Στοίβας 38 / / check i f stack i s empty 39 int stack_empty ( stack s ) 40 { 41 assert ( s ) ; 42 return s >head == NULL ; 43 } 44 45 / / get stack size 46 int stack_size ( stack s ) 47 { 48 assert ( s ) ; 49 return s >size ; 50 } 51 52 / / get newest stack element 53 datat stack_top ( stack s ) 54 { 55 assert ( s && s >head ) ; 56 return s >head >data ; 57 } Χαροκόπειο Πανεπιστήμιο 25/29
Υλοποίηση Στοίβας 58 void stack_push ( stack s, datat data ) 59 { 60 assert ( s ) ; 61 node n = ( node ) malloc ( sizeof ( struct noder ) ) ; 62 assert ( n ) ; 63 n >data = data ; 64 n >next = s >head ; 65 s >head = n ; 66 s >size++; 67 } 68 69 void stack_pop ( stack s ) 70 { 71 assert ( s && s >head ) ; 72 73 node ret = s >head ; 74 s >head = s >head >next ; 75 s >size ; 76 77 free ( ret ) ; 78 } Χαροκόπειο Πανεπιστήμιο 26/29
Υλοποίηση Στοίβας 79 / / destroy stack and f r e e memory 80 void stack_destroy ( stack s ) 81 { 82 while (! stack_empty ( s ) ) 83 stack_pop ( s ) ; 84 85 free ( s ) ; 86 } Χαροκόπειο Πανεπιστήμιο 27/29
Υλοποίηση Στοίβας 87 int main ( ) 88 { 89 int am ; 90 datat data ; 91 node n ; 92 stack s = stack_create ( ) ; 93 94 while ( ( data. c=getchar ( ) )!= EOF ) 95 stack_push ( s, data ) ; 96 97 while (! stack_empty ( s ) ) { 98 printf ( "%c", stack_top ( s ). c ) ; 99 stack_pop ( s ) ; 100 } 101 stack_destroy ( s ) ; 102 return 0; 103 } Χαροκόπειο Πανεπιστήμιο 28/29
Άλλες Δομές Δεδομένων Στα επόμενα έτη θα συναντήσετε μια πληθώρα δομών δεδομένων όπως δέντρα γραφήματα λεξικά κ.τ.λ Κάθε δομή δεδομένων έχει τα πλεονεκτήματα και μειονεκτήματα της. Χαροκόπειο Πανεπιστήμιο 29/29