cours 5 listes modi ables -...
TRANSCRIPT
Mlist Listes doublement chaınees Files
Conception de structures de donnees
Cours 5
Listes modifiables
5 avril 2013
Struct 1/31
Mlist Listes doublement chaınees Files
Listes modifiables vs. listes recursives
Listes recursives (Rlist)
fonctions recursives
pas de fonction de modification
actions possibles uniquement sur le 1er element
Consequence : pour modifier une liste, il faut la reconstruire !
Exemple : supprimer toutes les occurrence de e dans la liste l
.
Struct 3/31
Mlist Listes doublement chaınees Files
Listes modifiables vs. listes recursives
Listes recursives (Rlist)
fonctions recursives
pas de fonction de modification
actions possibles uniquement sur le 1er element
Consequence : pour modifier une liste, il faut la reconstruire !
Exemple : supprimer toutes les occurrence de e dans la liste l
Rlist deleteAllOcc(Element e, Rlist l){
if(isEmpty(l))
return newEmptyRlist();
else
if( car(l) == e )
return deleteAllOcc(e,cdr(l));
else return cons( car(l), deleteAllOcc(e,cdr(l)) );
}
Struct 3/31
Mlist Listes doublement chaınees Files
Listes modifiables : type Mlist
typedef ... Element; // type des elements de la liste
typedef struct cell{ // type des maillons de la liste
Element elem;
struct cell *next;
}Cell;
typedef Cell *Mlist; // type d’une liste (pointeur sur maillon)
Mlist newEmptyMlist(void);
int isEmpty(Mlist l);
Mlist cons(Element e, Mlist nxt);
Element car(Mlist l);
Mlist cdr(Mlist l);
Struct 4/31
Mlist Listes doublement chaınees Files
Fonctions de modification des listes chaınees
void insertFirst(Element e, Mlist *l); // insere en tete
void insertAfter(Element e, Cell *c); // insere ensuite
void insertLast(Element e, Mlist *l); // insere en fin
void insertPosition(Element e, Mlist *l, int pos);
// insere a une position donnee
Element deleteFirst(Mlist *l); // supprime en tete
Element deleteAfter(Cell *c); // supprime ensuite
Element deleteLast(Mlist *l); // supprime en fin
Element deletePosition(Mlist *l, int pos);
// supprime a une position donnee
Attention : toutes ces fonctions modifient les listes !
Struct 5/31
Mlist Listes doublement chaınees Files
Listes modifiables vs. recursives (suite)
Listes recursives (Rlist)
fonctions recursives
pas de fonction de modification
actions possibles uniquement sur le 1er element
Consequence : pour modifier une liste, il faut la reconstruire !
Listes modifiables
fonctions iteratives (boucles)
fonctions de modifications
actions possibles sur n’importe quel element
Attention : ces fonctions sont plus complexes a implanter !
Struct 6/31
Mlist Listes doublement chaınees Files
Listes modifiables vs. recursives (fin)
Rlist deleteAllOcc(Element e, Rlist l){
if(isEmpty(l))
return newEmptyRlist();
else if( car(l) == e )
return deleteAllOcc(e,cdr(l));
else return cons( car(l), deleteAllOcc(e,cdr(l)) );
} // reconstruction!
---------------------------------------------------------------------
void deleteAllOcc(Element e, Mlist *l){ // param: pointeur sur liste!
if(!isEmpty(*l)){
Mlist tmp=*l; // pointeur de parcours
while(!isEmpty(cdr(tmp))){
if(car(cdr(tmp))==e)
deleteAfter(tmp);
else tmp=cdr(tmp); // parcours sans reconstruction!
}
if( car(*l) == e )
deleteFirst(l);
}
}Struct 7/31
Mlist Listes doublement chaınees Files
Manipulation de listes chaınees
void insertFirst(Element e, Mlist *l){
Cell *new=cons(e,*l);
*l=new;
}
/* insere une cellule contenant e apres la cellule c */
void insertAfter(Element e, Cell *c){
if(isEmpty(c)) error("insertAfter impossible!");
Cell *new=cons(e,cdr(c));
c->next=new;
}
Struct 10/31
Mlist Listes doublement chaınees Files
Manipulation de listes chaınees - suite
void insertPosition(Element e, Mlist *l, int pos){
if(pos==0)
insertFirst(e,l);
else{
Mlist tmp=*l;
while(!isEmpty(tmp) && pos!=1){
tmp=cdr(tmp);
pos--;
}
if(pos!=1)
error("insertPosition impossible!");
else insertAfter(e,tmp);
}
}
Struct 11/31
Mlist Listes doublement chaınees Files
Manipulation de listes chaınees - suite
Element deleteFirst(Mlist *l){
if(isEmpty(*l))
error("deleteFirst impossible!");
Element e=car(*l);
*l=cdr(*l);
return e;
}
/* detruit la cellule suivant c */
Element deleteAfter(Cell *c){
if( isEmpty(c) || isEmpty(cdr(c)) )
error("deleteAfter impossible!");
Element e=car(cdr(c));
c->next=cdr(cdr(c));
return e;
}
Struct 12/31
Mlist Listes doublement chaınees Files
Manipulation de listes chaınees - suite
Element deleteLast(Mlist *l){
if(isEmpty(*l))
error("deleteLast impossible!");
if(isEmpty(cdr(*l))) /* la liste a 1 seul element */
return deleteFirst(l);
else{
Mlist tmp=*l;
while(!isEmpty(cdr(cdr(tmp))))
tmp=cdr(tmp);
return deleteAfter(tmp);
}
}
Struct 13/31
Mlist Listes doublement chaınees Files
Complexites comparees
Complexite Complexite
Operation tableau liste
Acces au ie element O(1) ? ?
Insertion en tete e O(n) ? ?
Insertion apres un element O(n) ? ?
Insertion en fin e O(1) ? ?
Suppression en tete e O(n) ? ?
Suppression apres un element O(n) ? ?
Suppression en fin O(1) ? ?
Manipulations des tableaux et des listes, complexite desoperations preservant l’ordre relatif des elements.
Struct 14/31
Mlist Listes doublement chaınees Files
Complexites comparees
Complexite Complexite
Operation tableau liste
Acces au ie element O(1) O(n)
Insertion en tete e O(n) O(1)
Insertion apres un element O(n) O(1)
Insertion en fin e O(1) O(n)
Suppression en tete e O(n) O(1)
Suppression apres un element O(n) O(1)
Suppression en fin O(1) O(n)
Manipulations des tableaux et des listes, complexite desoperations preservant l’ordre relatif des elements.
Struct 14/31
Mlist Listes doublement chaınees Files
Simplement chaınee vs. doublement chaınee
Points communs :
Structures permettant de stocker une collection de donneesde meme type.
L’espace memoire utilise n’est pas contigu.
La taille est inconnue a priori ;
Une liste doublement chaınee est constituee de cellulesqui sont liees entre elles par des pointeurs.
Pour acceder a un element quelconque d’une liste, il fautparcourir la liste jusqu’a cet element.
Differences :
Une liste doublement chaınee n’est PAS recursive !
On peut acceder directement au premier et dernier element.
On peut parcourir la liste dans les 2 sens (on peut doncrevenir en arriere).
Struct 16/31
Mlist Listes doublement chaınees Files
Representation graphique
liste vide:
liste contenant 1 élément:
liste contenant 3 éléments:
first last first last
3
17 14
first last
Struct 17/31
Mlist Listes doublement chaınees Files
Definition d’une liste doublement chaınee en C
typedef int Element;
typedef struct cell{
Element elem;
struct cell *next; /* pointeur vers la cellule suivante */
struct cell *prev; /* pointeur vers la cellule precedente */
}Cell;
typedef struct{ /* attention, une DList n’est pas un pointeur! */
Cell *first;
Cell *last;
} DList;
DList newEmptyDList(void){
return (DList){NULL,NULL};
}
Struct 18/31
Mlist Listes doublement chaınees Files
Definition d’une liste doublement chaınee - suite
int isEmptyDList(DList l){
if( (l.first==NULL && l.last!=NULL) ||
(l.first!=NULL && l.last==NULL))
error("DList mal formee!");
/* n’arrive pas si la DList est utilisee correctement */
return l.first==NULL; /* ou l.last==NULL */
}
Cell *newCell(Cell *prv, Element e, Cell *nxt){
Cell *c;
if ((c=(Cell *)malloc(sizeof(Cell)))==NULL)
error("Allocation ratee!");
c->elem=e;
c->next=nxt;
c->prev=prv;
return c;
}
Struct 19/31
Mlist Listes doublement chaınees Files
Manipulation de listes doublement chaınees
Fonctions pour inserer ou supprimer des elements dans une listedoublement chaınee :
void insertFirst(Element e, DList *l);
void insert(Element e, Cell *c, DList *l);
void insertLast(Element e, DList *l);
void insertPosition(Element e, int pos, DList *l);
Element deleteFirst(DList *l);
Element delete(Cell *c, DList *l);
Element deleteLast(DList *l);
Element deletePosition(DList *l, int pos);
Attention : ces fonctions modifient les listes ;elles ne fabriquent pas des copies !
Struct 20/31
Mlist Listes doublement chaınees Files
Insertion a la place d’une cellule
17 14
lastfirst c
Struct 22/31
Mlist Listes doublement chaınees Files
Insertion a la place d’une cellule
17 14
lastfirst
28new
c
Struct 22/31
Mlist Listes doublement chaınees Files
Insertion a la place d’une cellule
17 14
lastfirst
28new
c
Struct 22/31
Mlist Listes doublement chaınees Files
Insertion a la place d’une cellule
17 14
lastfirst
28new
c
Struct 22/31
Mlist Listes doublement chaınees Files
Manipulation de listes doublement chaınees - 1
void insertFirst(Element e, DList *l){
Cell *new=newCell(NULL,e,l->first);
if(!isEmptyDList(*l))
(l->first)->prev=new;
else l->last=new; /* 1 cellule: first=last */
l->first=new;
}
void insert(Element e, Cell *c, DList *l){
if(c==l->first)
insertFirst(e,l);
else /* c==l->last n’est pas un cas particulier */
if(!isEmptyDList(*l) && c!=NULL){
Cell *new=newCell(c->prev,e,c);
c->prev=new;
(new->prev)->next=new;
}
else error("insert impossible!");
}Struct 23/31
Mlist Listes doublement chaınees Files
Manipulation de listes doublement chaınees - 2
void insertLast(Element e, DList *l){
Cell *new=newCell(l->last,e,NULL);
if(!isEmptyDList(*l))
(l->last)->next=new;
else l->first=new;
l->last=new;
} /* exactement le meme principe que insertFirst */
Element deleteFirst(DList *l){
if(isEmptyDList(*l))
error("deleteFirst impossible!");
Element e=(l->first)->elem; /* sauvegarde */
l->first=(l->first)->next;
if(l->first==NULL)
l->last=NULL;
else (l->first)->prev=NULL;
return e;
}
Struct 24/31
Mlist Listes doublement chaınees Files
Manipulation de listes doublement chaınees - 3
Element delete(Cell *c, DList *l){
if(c==NULL || isEmptyDList(*l))
error("delete impossible!");
if(c==l->first) /* ou c->prev==NULL */
l->first=c->next;
if(c==l->last) /* ou c->next==NULL */
l->last=c->prev;
Element e=c->elem; /* sauvegarde */
if(c->next!=NULL)
(c->next)->prev=c->prev;
if(c->prev!=NULL)
(c->prev)->next=c->next;
return e;
}
Struct 25/31
Mlist Listes doublement chaınees Files
Manipulation de listes doublement chaınees - 4
Element deletePosition(DList *l, int pos){
if(isEmptyDList(*l))
error("deletePosition impossible!");
if(pos==0)
return deleteFirst(l);
else{
Cell *tmp=l->first;
while(tmp->next!=NULL && pos!=0){tmp=tmp->next;
pos--;
} /* recherche de l’endroit ou supprimer */
if(pos!=0) /* c-a-d tmp->next==NULL */
error("deletePosition impossible!");
return delete(tmp, l);
}
}
Struct 26/31
Mlist Listes doublement chaınees Files
Complexites comparees
Complexite
Operation tableau liste liste d.c.
Acces au ie element O(1) O(n)
Insertion en tete O(n) O(1)
Insertion au niveau d’1 element O(n) O(1)
Insertion en fin O(1) O(n)
Suppression en tete O(n) O(1)
Suppression au niveau d’1 element O(n) O(1)
Suppression en fin O(1) O(n)
Manipulations des tableaux et des listes, complexite desoperations preservant l’ordre relatif des elements.
Struct 27/31
Mlist Listes doublement chaınees Files
Complexites comparees
Complexite
Operation tableau liste liste d.c.
Acces au ie element O(1) O(n) O(n)
Insertion en tete O(n) O(1) O(1)
Insertion au niveau d’1 element O(n) O(1) O(1)
Insertion en fin O(1) O(n) O(1)
Suppression en tete O(n) O(1) O(1)
Suppression au niveau d’1 element O(n) O(1) O(1)
Suppression en fin O(1) O(n) O(1)
Manipulations des tableaux et des listes, complexite desoperations preservant l’ordre relatif des elements.
Struct 27/31
Mlist Listes doublement chaınees Files
Qu’est-ce qu’une file ?
Une file (queue) est une structure de donnees fondee sur leprincipe “premier arrive, premier sorti” (FIFO : First In, FirstOut). Les premiers elements ajoutes a la file sont les premiers aetre recuperes (penser a une file d’attente, par exemple).
On peut acceder au premier element (le prochain a sortirnextOut) et au dernier element (le dernier arrive prevIn).
On peut defiler le premier element (removeFromFifo).
On peut enfiler un element a la fin (insertInFifo).
Il faut pouvoir detecter si elle est vide (et eventuellementsi elle est pleine).
Il est possible d’implanter des files en C en utilisant destableaux, des listes ou des listes doublement chaınees.
Struct 29/31
Mlist Listes doublement chaınees Files
FIFO : Complexites comparees
Complexite
Operation tableau liste liste d.c.
next out O(1) O(1) O(1) O(1)
previous in O(1) O(1) O(n) O(1)
insert in Fifo O(1) O(1) O(n) O(1)
remove from Fifo O(n) O(1) O(1) O(1)
Tableaux avec decalages : nombre d’elements limite
Tableaux sans decalages : nombre d’ajouts limite
Struct 30/31
Mlist Listes doublement chaınees Files
Definir une file comme liste doublement chaınee
typedef DList Fifo;
int isEmptyFifo(Fifo f){ return isEmptyDList(f); }
Fifo newEmptyFifo(void){ return createEmptyDList(); }
void insertInFifo(Element e, Fifo* f){ insertFirst(e,f); }
Element removeFromFifo(Fifo* f){
if(isEmptyFifo(*f)) error("pas d’element dans une file vide!");
return deleteLast(f);
}
Element prevIn(Fifo f){
if(isEmptyFifo(f)) error("pas d’element dans une file vide!");
return (f.first)->elem;
}
Element nextOut(Fifo f){
if(isEmptyFifo(f)) error("pas d’element dans une file vide!");
return (f.last)->elem;
}Struct 31/31