Structure de donn - PowerPoint PPT Presentation

About This Presentation
Title:

Structure de donn

Description:

cas 1: aucun autre l ment ajout . if (premier == null) premier = new ... cas 1: aucun autre l ment ajout . if (premier == null) premier = new Noeud(v,null) ... – PowerPoint PPT presentation

Number of Views:43
Avg rating:3.0/5.0
Slides: 59
Provided by: NIE125
Category:

less

Transcript and Presenter's Notes

Title: Structure de donn


1
Structure de données Liste
  • IFT1025, Programmation 2
  • Jian-Yun Nie

2
Points importants
  • Utilité dune structure de données
  • Comment utiliser une structure de données de
    liste existante
  • Comment programmer pour gérer soi-même une liste
  • Dautres structures souvent utilisées en
    informatique (arbre, pile, )

3
Pourquoi une structure de données?
  • Structure de données
  • Une organisation des informations
  • Pour regrouper une série de données de nature
    similaire (tableau, liste, )
  • Pour mieux regrouper les informations pour le
    même concept (classe, )
  • Traditionnellement
  • Structure de données
  • Traitement
  • Maintenant
  • Classe structure de données et traitements

4
Structures de données déjà vues
  • Tableau (Array) pour organiser une séquence de
    données
  • int a new int 10
  • Similairement String
  • Classe pour regrouper les attributs du même
    concept
  • public class C
  • int a
  • String name
  • C ref new C()


a
ref
int a String name
0
null
5
Liste
  • Utilité pour organiser une séquence de données
  • Une structure plus flexible que tableau

Tableau Liste
Taille fixe Taille variable
Ordre entre éléments Ordre selon les liens
Insertion et enlèvement difficile Plus facile
Accès rapide Plus lent
6
Illustration
  • Entête (Tête) réfère au premier noeud
  • noeuds enchaînés
  • Chaque noeud enchaîné
  • Valeur stockée (A, B, )
  • Référence (lien, pointeur) vers le prochain nœud

7
Structure de données Liste
  • Deux parties
  • Structure pour lentête
  • Référence vers le premier nœud
  • Dautres attributs optionnels
  • Référence vers le dernier nœud
  • Nombre de nœuds
  • Structure pour nœud
  • Structure (ou classe) pour le stockage dune
    valeur
  • Référence vers le prochain nœud
  • Optionnel
  • Référence vers le nœud précédent (liste
    doublement chaînée)

8
Définition dune liste simplement chaînée
  • Entête contenant une référence
  • public class Liste
  • Noeud premier
  • // méthodes pour traiter une liste
  • Nœud contenant un int
  • public class Noeud
  • int valeur
  • Noeud prochain
  • public Noeud (int v, Noeud p)
  • valeur v
  • prochain p

9
Création
  • Créer une entête
  • Liste l new Liste()
  • Créer des nœuds
  • l.premier new Noeud(1,
  • new Noeud(2,
  • new Noeud(3,null)))

l

null
l

1
2
3
null
10
Traverser une liste (tout se fait dans Liste)
  • public class Liste
  • public void print()
  • Noeud n premier
  • while (n!null)
  • System.out.print(n.valeur "-gt")
  • n n.prochain
  • System.out.println("null")
  • 1-gt2-gt3-gtnull

11
Trouver un élément
  • public class Liste
  • public Noeud trouver(int v)
  • Noeud n premier
  • while (n ! null n.valeur ! v)
  • n n.prochain
  • return n

12
Déterminer la longueur
  • public class Liste
  • public int longueur()
  • Noeud n premier
  • int nb0
  • if (premier null) return 0
  • while (n ! null)
  • nb
  • n n.prochain
  • return nb

13
Ajouter un élément au début
  • public class Liste
  • public void ajoutDebut(int v)
  • premier new Noeud(v, premier)

l

1
2
3
null
5
14
Ajouter un élément à la fin
  • public class Liste
  • public void ajoutFin(int v)
  • Noeud n premier
  • // cas 1 aucun autre élément ajouté
  • if (premier null) premier new
    Noeud(v,null)
  • // cas 2 il y a déjà des éléments
  • else
  • while (n.prochain ! null) n n.prochain
  • n.prochain new Noeud(v,null)
  • Attention tester sur le prochain
  • Pas de limite de taille

l

1
2
3
null
5
n
15
Enlever un élément
  • Besoin de garder la référence sur le précédent
    élément
  • Tester sur le prochain
  • public class Liste
  • public void enlever(int v)
  • Noeud n premier
  • // cas 1 Si le premier est null
  • if (premier null) return
  • // cas 2 Si le premier est à enlever
  • if (premier.valeur v)
  • premier premier.prochain
  • return // On pourrait aussi vouloir retourner
    le neoud enlevé
  • // cas 3 sinon, tester sur les autres éléments
  • while (n.prochain ! null n.prochain.valeur
    ! v) n n.prochain
  • if (n.prochain ! null) n.prochain
    n.prochain.prochain

Attention à lordre des tests
16
Concatenation de 2 listes
  • public class Liste
  • public void concat(Liste l)
  • if (premier null)
  • premier l.premier
  • return
  • Noeud n premier
  • while (n.prochain ! null) nn.prochain
  • n.prochain l.premier

// Aller à la fin
17
Traitement récursif
  • Itératif Liste suite déléments
  • Traitement typique parcourir la liste avec while
  • Récursif Liste un élément reste (une plus
    petite liste)
  • Traitement récursif
  • Traiter un élément
  • Traiter le reste par un appel récursif
  • Décomposition générale
  • Cas 1 liste vide ou un seul élément (cas darrêt
    de récursion)
  • Cas 2 liste non vide
  • Lélément courant
  • Appel récursif pour la suite

18
Déterminer la longueur(Deux niveaux de
traitement)
  • Longueur
  • 1, si la liste contient un seul élément
  • 1 longueur du reste, sinon.
  • public class Liste
  • Noeud premier
  • public int longueur()
  • if (premier null) return 0
  • else return premier.longueur()
  • public class Nœud // Premier option utiliser la
    récursion sur les noeuds
  • public int longueur()
  • // cas 1 pas de récursion
  • if (prochainnull) return 1
  • // cas 2 récursion
  • else return 1 prochain.longueur()

Cet appel est possible seulement quand
premier!null
19
Structure générale
  • Class Liste
  • public int longueur()
  • appel à la méthode de Nœud
  • Class Nœud
  • public int longueur()
  • Cas simple retourner 1
  • Cas complexe 1 appel récursif

20
Déterminer la longueur (bis)
  • public class Liste
  • Noeud premier
  • public int longueur()
  • return longueur(premier)
  • // Deuxième option utiliser la récursion dans
    Liste, avec nœud comme paramètre
  • public int longueur(Noeud n)
  • if (nnull) return 0
  • else return 1 longueur(n.prochain)

Cet appel est possible même si premiernull
21
Structure générale
  • Classe Liste
  • public int longueur()
  • appel à une méthode avec Nœud comme paramètre
  • public int longueur(Nœud n)
  • déterminer la longueur à partir du nœud n

22
Ajouter à la fin
  • public class Liste
  • public void ajoutFin(int v)
  • // cas 1 aucun autre élément ajouté
  • if (premier null) premier new
    Noeud(v,null)
  • // cas 2 il y a déjà des éléments
  • else premier.ajoutFin(v)
  • public class Noeud
  • public void ajoutFin(int v)
  • if (prochain null) prochain new
    Noeud(v,null)
  • else prochain.ajoutFin(v)

Traiter le cas dune liste vide
Ajouter un élément dans une liste non-vide
23
Ajouter à la fin (bis)
  • public class Liste
  • public void ajoutFin(int v)
  • // cas 1 aucun autre élément ajouté
  • if (premier null) premier new
    Noeud(v,null)
  • // cas 2 il y a déjà des éléments
  • else ajoutFin(premier, v)
  • public void ajoutFin(Noeud n, int v)
  • if (n.prochain null) n.prochain new
    Noeud(v,null)
  • else ajoutFin(n.prochain,v)

24
Ajouter à la fin (bis-bis)
  • public class Liste
  • public void ajoutFin(int v)
  • premier ajoutFin(premier, v)
  • public Noeud ajoutFin(Noeud n, int v)
  • if (n null) return new Noeud(v,null)
  • else
  • n.prochain ajoutFin(n.prochain,v)
  • return n

25
Réflexions
  • Les façons récursives dimplanter les autres
    méthodes
  • Enlever un élément
  • Ajouter au début
  • Insérer dans lordre
  • Inverser la liste
  • Concaténer deux liste
  • Obtenir le i-ième noeud

26
Complexité des opérations
  • Longueur O(n)
  • Trouver un élément O(n)
  • Enlever un élément O(n)
  • Ajouter au début O(1)
  • Ajouter à la fin O(n)
  • Améliorable ?

27
Liste simplement chaînée amélioration
  • Ajouter une référence au dernier élément pour
    faciliter lajout à la fin
  • public class Liste
  • Noeud premier
  • Noeud dernier
  • public void ajoutFin(int v)
  • if (premiernull) premier dernier new
    Noeud(v,null)
  • else
  • dernier.prochain new new Noeud(v,null)
  • dernier dernier.prochain

28
Liste doublement chaînée
  • Référence vers le prochain nœud
  • Référence vers le précédent nœud (permettre de
    reculer)
  • public class Noeud
  • int valeur
  • Noeud prochain
  • Noeud precedent

29
Exemple Enlever
  • public class Liste
  • public void enlever(int v)
  • Noeud n premier
  • if (premier null) return
  • if (premier.valeur v)
  • premier premier.prochain
  • if (premiernull) dernier null
  • return
  • while (n ! null n.valeur ! v) n
    n.prochain
  • if (n ! null)
  • n.precedent.prochain n.prochain
  • n.prochain.precedent n.predcedent

null
1
2
3
n
30
Généralisation
  • Définir un nœud pour contenir tout Object
  • public class Noeud
  • Object element
  • Noeud prochain
  • Noeud precedent

31
Réflexion
  • Adapter les traitements à cette structure
    générale avec Object
  • Comment faire pour pouvoir trier une liste?

32
Tableau v.s. Liste
  • Tableau (array)
  • Taille fixe
  • Accès rapide avec index (O(1))
  • Ajouter/enlever un élément plus difficile (O(n))
  • À utiliser si
  • Beaucoup daccès aléatoire
  • Pas besoin de modifier souvent lordre des
    éléments
  • Nombre déléments à stocker déterminée (ou une
    limite existe)
  • Liste
  • Taille flexible
  • Accès plus lent (O(n))
  • Ajouter/enlever un élément plus facile (O(1))
  • À utiliser si
  • Peu daccès aléatoire (souvent un parcours de
    tous les éléments)
  • Nombre délément très variable
  • Éléments sont souvent re-ordonnés, ajoutés ou
    enlevés

33
Allocation de mémoire
  • La mémoire est allouée quand on crée un nœud
  • Les nœuds enlevés ne sont plus utilisés
  • Gabbage collector récupère les mémoires qui ne
    sont plus utilisées
  • Pas besoin de gérer lallocation et désallocation
    de mémoire en Java
  • On ne peut pas contrôler quand le gabbage
    collector sera lancé (dépend de limplantation de
    JVM)
  • finalize() la méthode héritée de Object, mais
    quon peut remplacer
  • Définir des opérations à effectuer quand le
    gabbage collector va récupérer cette mémoire.
  • Ne permet pas dévoquer le gabbage collector
  • À utiliser dans certains cas spéciaux (e.g. pour
    évoquer delete dun objet en C, utilisé en Java)

34
De limplantation vers un type abstrait
  • Implantation de Liste pour les éléments contenant
    int, Object, etc.
  • Généralisation
  • Définir les opérations sur la liste pour tout
    type de données
  • Les opérations communes sur une liste (interface
    List)
  • boolean add(Object o) Ajouter à la fin
  • void add(int index, Object o) Ajouter à une
    position
  • void clear() Enlever tout
  • boolean contains(Object o) Contanir un élément?
  • boolean isEmpty() Vide?
  • boolean remove(Object o) Enlever le premier o
  • int size() nombre déléments
  • Iterator irerator() Iterator permet de
    parcourir les éléments

35
Implantation avec une liste chaînée
  • LinkedList
  • public class LinkedListltEgt extends
  • AbstractListltEgt
  • private class Node
  • private E element
  • private Node next
  • // Create a Node containing specified element.
  • public Node (E element)
  • this.element element
  • this.next null
  • // end of class Node
  • // end of class LinkedList

36
Implantation LinkedList
  • public class LinkedListltEgt extends
    AbstractListltEgt
  • private int size
  • private Node first
  • // Create an empty LinkedListltEgt.
  • public LinkedList ()
  • size 0
  • first null

37
Implantation LinkedList
  • Une méthode interne pour obtenir le i-ième
    élément
  • /
  • The i-th node of this LinkedList.
  • The LinkedList must be non-empty.
  • require 0 lt i i lt this.size()
  • /
  • private Node getNode (int i)
  • Node p first
  • int pos 0 // p is pos-th Node
  • while (pos ! i)
  • p p.next
  • pos pos 1
  • return p

public E get (int index) Node p
getNode(index) return p.element
38
Implantation LinkedList
  • Enlever le i-ième élément
  • public void remove (int index)
  • if (index 0)
  • first first.next
  • else
  • Node p getNode(index-1)
  • p.next p.next.next
  • size size - 1

39
Implantation avec tableau?
  • ArrayList implante linterface List avec un
    tableau
  • Possède une taille limite, mais est agrandi
    automatiquement de 50 au besoin
  • Accès rapide avec un indexe
  • Ajouter un élément O(n) pour déplacer les
    éléments

40
Méthodes de ArrayList
  • void add(int index, Object o)
  • boolean add(Object o) ajouter à la fin
  • void clear()
  • boolean contains(Object o)
  • void ensureCapacity(int minCapacity) assurer
    quil y a des places nécessaires
  • boolean isEmpty()
  • Object remove(int index)
  • Object set(int index, Object o)
  • int size() numbre déléments dans la liste
  • void trimtosize() enlever les espaces non
    utilisé

41
Opération de tri sur une liste
  • public class Liste
  • Noeud premier, dernier
  • public void concatener(Liste l) // à
    réfléchir
  • public void quicksort()
  • if (premier null) return
  • Liste l1 new Liste()
  • Liste l2 new Liste()
  • this.separer(premier.valeur, l1, l2)
  • l1.quicksort()
  • l2.quicksort()
  • l1.concatener(l2)
  • premier l1.premier

42
Opération de tri sur une liste
  • private separer(int pivot, Liste l1, Liste l2)
  • Noeud n premier
  • while (n!null)
  • if (n.valeurltpivot) l1.ajoutFin(n.valeur)
  • else l2.ajoutFin(n.valeur)
  • À réfléchir généralisation - trier une liste
    contenant des éléments Comparable

43
Iterator
  • Permet de parcourir sur les éléments dune liste
    (ou de nimporte quel ensemble)
  • Référence courant Position courante (initialisée
    au premier)
  • Utilisation
  • LinkedList list
  • Iterator iter list.iterator()
  • while (iter.hasNext())
  • Object obj iter.next()
  • // do something with obj

44
Interface Interator
  • boolean hasNext()
  • Object next() retourner lélément courant, et
    avancer la référence courante au prochain
  • void remove() enlever lélément courant, la
    référence courante réfère au prochain élément

45
Implanter Iterator pour Liste (ex.)
  • public class Liste
  • Noeud premier, dernier, courant
  • public ListeIterator iterator()
  • return new ListeIterator(this)
  • public class ListeIterator implements Iterator
  • private Liste liste
  • private Noeud courant
  • public ListeIterator(Liste liste) this.liste
    liste courantliste.premier
  • public boolean hasNext() return courant !
    null
  • public Object next() return courant if
    (hasNext()) courant courant.prochain
  • public void remove() throw new
    UnsupportedOperationException()
  • Liste liste ...
  • for (Iterator i liste.iterator() i.hasNext() )
  • Object obj i.next()
  • // do something with obj

46
Dautres types de données
  • Pile (stack) premier entré, dernier sorti
  • Empiler un élément
  • Dépiler un élément
  • Test isEmpty()
  • Queue premier entré, premier sorti
  • Mettre dans la queue (enqueue)
  • Enlever de la queue (dequeue)
  • Test isEmpty()
  • Implantations (à réfléchir)
  • Avec tableau (circulaire)
  • Avec liste



47
Arbre de recherche binaire
  • Arbre
  • Racine
  • Enfants
  • Chaque nœud a un parent
  • au plus
  • (0 parent pour racine)
  • Arbre binaire
  • Un parent peut avoir
  • 2 enfants au plus

48
Arbre de recherche binaire
  • Arbre de recherche binaire
  • Organiser les nœuds selon leurs valeurs
  • Branche gauche valeurs lt valeur du parent
  • Branche gauche valeurs gt valeur du parent

7
5
9
3
7
10
49
Pourquoi arbre de recherche binaire?
  • Recherche dans une liste O(n)
  • Recherche dans un arbre de recherche binaire,
    selon une valeur v
  • Valeur de racine r v?
  • Sinon
  • Si v lt r, chercher à gauche
  • Sinon, chercher à droite
  • Si larbre est balancé O(log n)

50
Implantation en Java
  • class Noeud
  • int valeur
  • Noeud gauche, droite
  • public Noeud(int v, Noeud g, Noeud d)
  • valeur v
  • gauche g
  • droire d
  • class Arbre
  • Noeud racine
  • public void add(int v)

51
Insertion dun noeud
  • // Dans la classe Arbre
  • public void add(int v)
  • if (racine null) racine new Noeud(v, null,
    null)
  • else racine.add(v)
  • // Dans la classe Noeud
  • public void add(int v)
  • if (v lt valeur)
  • if (gauche null) gauche new
    Nœud(v,null,null)
  • else gauche.add(v)
  • else
  • if (droite null) droite new
    Nœud(v,null,null)
  • else droite.add(v)

52
Chercher un noeud
  • // Dans la classe Arbre
  • public Noeud chercher(int v)
  • if (racine null) return null
  • else return racine.chercher(v)
  • // Dans la classe Nœud
  • public Noeud chercher(int v)
  • if (v valeur) return this
  • else if (v lt valeur gauche ! null) return
    gauche.chercher(v)
  • else if (v gt valeur droite ! null) return
    droite.chercher(v)
  • else return null

53
Enlever un noeud
7
5
9
  • Si le nœud à enlever est une feuille
  • Cas simple
  • Si le nœud à enlever à une seule branche (5)
  • Relier la branche directement au parent
  • Sinon (7)
  • Identifier le nœud juste supérieur (le nœud la
    plus à gauche dans la branche à droite) (8)
  • Remplacer le nœud à enlever par ce noeud

3
8
10
7
3
9
10
8
8
3
9
10
54
Transformer une liste en un arbre
  • Pour accélérer laccès (recherche)
  • Insérer les nœud lun après lautre dans larbre
  • Problème de larbre non balancé (dégénéré)
  • Liste 1, 2, 3, 4, 5, 6
  • Solution
  • (essayez de le faire)
  • Trier la liste
  • Le milieu comme racine
  • Profondeur O(log n)

1
2
3
4
5
6
55
Résumé
  • Structure de données
  • Pour organiser les données
  • Tableau (array), liste
  • Liste
  • Structure flexible
  • Adaptée pour des mises à jour fréquentes
  • Type abstrait de données - généralisation
  • Correspond à un ensemble dopérations bien
    définies
  • Implantation dun type de donnée
  • Différentes façons LinkedList, array, etc.
  • Iterator
  • Dautres types de données pile, queue, arbre

56
Exercices à réfléchir
  • Réfléchir sur les opérations sur un arbre de
    recherche binaire, dont chaque nœud contient un
    int
  • Comment généraliser ces opérations pour quelles
    fonctionnent avec des nœuds contenant des objets
    Comparable
  • Insertion dans larbre
  • Enlever un nœud contenant une élément
  • Rechercher un élément
  • Optimiser la structure essayer de balancer
  • Utilisation de larbre de recherche binaire pour
    faire du tri (complexité?)
  • Arbre n-aire
  • Trie
  • Arbre de Briandais

57
Trie
  • Pour stocker des mots de façon plus conpacte
  • a, ab, abc, acb, aa, bac
  • Une réalisation
  • Chaque nœud contient un tableau de 26 cases
    (caractères)
  • Chaque case se dirige vers un nœud enfant

a
b
a
b
c
a
a
c
b
58
Arbre de Briandais
  • Représenter un arbre n-aire quelconque en un
    arbre binaire
  • Nœud
  • Info
  • Premier enfant
  • sibling

a
a
a
b
c
a
b
c
c
b
e
f
c
b
e
f
Write a Comment
User Comments (0)
About PowerShow.com