You are on page 1of 24

.

Cours 7 Files d’attente – Piles Graphes non orient´s e
Jean-Jacques.Levy@inria.fr http://jeanjacqueslevy.net tel: 01 39 63 56 89
secr´tariat de l’enseignement: e

Catherine Bensoussan cb@lix.polytechnique.fr Aile 00, LIX tel: 01 69 33 34 67

http://www.enseignement.polytechnique.fr/informatique/
1

.

Plan
1. Files d’attente 2. Piles 3. Graphes 4. Repr´sentation des graphes e 5. Parcours en profondeur d’abord 6. Parcours en largeur d’abord 7. Arbres de recouvrement 8. Connexit´ et sortie de labyrinthe e 9. Biconnexit´. e

2

FIFO (int n) { debut = 0. e Une premi`re m´thode compacte consiste ` g´rer un tampon e e a e circulaire. First Out). fin = 0. } 3 . pleine. fin. vide = true. contenu = new int[n]. contenu. premier servi (First In. Files d’attente repr´sent´e par un tampon circulaire e e Premier arriv´. class FIFO { int boolean int[] debut. etc. le hardware.. le temps-r´el. Structure de e donn´es tr`s fr´quente dans les programmes: par exemple dans e e e les OS. vide. pleine = false.

Complexit´ en O(1).contenu. f.fin == f. f.length.contenu[f. e e e 4 .debut. f.debut]. File d’attente repr´sent´e par un tampon circulaire e e static void ajouter (int x. f."). } static int supprimer (FIFO f) { if (f. int res = f. } Belle sym´trie de ces proc´dures.pleine) throw new Error ("File Pleine.").debut. f.contenu. return res. f.debut + 1) % f.debut = (f.fin] = x..pleine = f.vide = f.vide = false.contenu[f. f.pleine = false.length.fin + 1) % f.fin == f.vide) throw new Error ("File Vide. FIFO f) { if (f.fin = (f.

fin = f. } } 5 . FIFO () { debut = null.debut == null) throw new Error ("File Vide. } } static int supprimer (FIFO f) { if (f.suivant = new Liste (x).fin = new Liste (x). else { int res = f.debut. else { f. fin = null.suivant. if (f.").debut = f. File d’attente repr´sent´e par une liste e e class FIFO { Liste debut.fin = null.debut = f. fin.. f.debut.suivant.fin) f.val.debut = f.fin. return res. FIFO f) { if (f. } static void ajouter (int x.fin.debut == f.fin == null) f. else f.

").contenu.1] = x. p. if (p. e class Pile { int hauteur .contenu [--p. int contenu[].hauteur <= 0) throw new Error ("Pile vide. On a e peut la repr´senter par un tableau ou une liste.hauteur . return p."). Pile p) { ++p.hauteur >= p.contenu[p. contenu = new int[n]. First Out). Pile (int n) {hauteur = 0. Pile repr´sent´e par un tableau e e Une pile correspond ` la strat´gie LIFO (Last In.. } 6 .hauteur]. } static int depiler (Pile p) { if (p.hauteur. } static void empiler (int x.length) throw new Error ("Pile pleine.

et en empilant les valeurs et op´rateurs rencontr´s et en faisant des op´rations entre le e e e sommet et le sous-sommet de la pile. int res = p. } static int depiler (Pile p) { if (p.suivant.sommet = p. Pile () { sommet = null. 1960 ⇒ compilateur). 7 . } static void empiler (int x.."). p.sommet). Pile repr´sent´e par une liste e e class Pile { Liste sommet. par un parcours suffixe de l’ASA. Pile p) { p. return res.val. Idem pour l’´valuation des expressions arithm´tiques avec une e e pile.sommet = new Liste (x.sommet.sommet == null) throw new Error ("Pile vide.sommet. p. } R´cursif = It´ratif + Pile e e (Randell et Russel.

(Makefile) e Un arbre est un dag. e e Exemples: les rues de Paris. 8 . le plan du m´tro. Un circuit (ou cycle) est u un chemin o` ext(vn ) = org(v1 ). o` n ≥ 0. les couloirs de l’X. telle que org(vi+1 ) = ext(vi ) pour 1 ≤ i < n. . n1 ) ∈ V . . vn . Une forˆt (ensemble d’arbres disjoints) est e un dag. v2 . Graphe Un graphe G = (V.. E) a un ensemble de sommets V et d’arcs E ⊂ V × V . V ) est un graphe non orient´ ssi (n1 . Par exemple. Un chemin est une suite d’arcs v1 . n2 ) a pour origine org(v) = n1 et pour extr´mit´ ext(v) = n2 . Un arc v = (n1 . Exemple: le graphe des d´pendances inter modules pour e la cr´ation d’un projet informatique. e e G = (N. . n2 ) ∈ V implique (n2 . u Les dag (directed acyclic graphs) sont des graphes orient´s sans e cycles.

. Exemple de graphe 000 100 010 101 110 111 011 001 Graphe de de Bruijn 9 .

. Exemple de graphe 2 4 8 6 10 12 9 5 7 3 Graphe des diviseurs 11 10 .

succ[x]). } 11 . Repr´sentations d’un graphe e En gros. } • Tableau de listes de successeurs: class Graphe { Liste[] succ. o` mi. } static void ajouterArc (Graphe g.. } static void ajouterArc (Graphe g. ++i) for (int j = 0. int x. nj ) est un arc du u graphe. deux m´thodes: e • Matrice de connexion M . j <= n. Matrice sym´trique pour un graphe non orient´. e e class Graphe { boolean[][] = m.m[i][j] = true.succ[x] = new Liste (y.j = 1 ssi (ni . int y) { g. Graphe (int n) { m = new int[n][n]. for (int i = 0. i <= n. Graphe (int n) { succ = new Liste[n]. int x. int y) { g. g. ++j) m[i][j] = false.

} } trouverArticulations (g).println(e). y. imprimerArticulations (g).. if (0 <= x && x < n && 0 <= y && y < n) { ajouterArc(g.parseInt(s).parseInt(st. } } 12 . try { String s = in.nextToken()).err.readLine()) != null) { StringTokenizer st = new StringTokenizer(s).parseInt(st.in)). y). int n = Integer. x. Entr´e du graphe e public static void main (String[] args) { BufferedReader in = new BufferedReader(new InputStreamReader(System. int x = Integer. Graphe g = new Graphe (n). } catch (IOException e) { System. ajouterArc(g.nextToken()). int y = Integer. x). while ((s = in.readLine().

. Depth-First Search 0 2 1 6 5 7 4 8 2 6 4 10 12 9 9 5 8 7 3 10 3 11 13 . Parcours en profondeur d’abord.

static int[] num. static void visit (Graphe g) { id = -1. ++x) for (int x = 0. x < g.length. num = new int[g. ls = ls. if (num[y] == -1) dfs(g. x < g. ls != null.succ. for (int ls = g. } } Son temps est en O(V + E).val. Aussi appel´ arborescences de Tr´maux dans le polycopi´.suivant) { int y = ls.succ[x]. x).succ. int x) { num[x] = ++id. y). e e e e static int id. } num[x] = -1. Depth-First Search Tarjan (1972) a d´montr´ l’utilit´ de cette m´thode. for (int x = 0.length. static void dfs (Graphe g.succ. ++x) if (num[x] == -1) dfs(g..length]. Parcours en profondeur d’abord. e e e 14 .

Arbres de recouvrement L’arbre des appels r´cursifs ` dfs est un arbre de recouvrement e a (spanning tree). il n’y a que les arcs du type e 1-2.] 15 . Les arcs d’un arc sont de 4 sortes: • d’un noeud de l’arbre ` un de ses fils dans l’arbre a • d’un noeud de l’arbre ` un de ses anc`tres dans l’arbre a e • d’un noeud de l’arbre ` un de ses descendants non direct a dans l’arbre • d’un noeud ` un de ses cousins dans l’arbre a [Dans dfs d’un graphe non orient´..

. Arbre de recouvrement – spanning tree 0 2 1 6 5 7 4 8 2 6 4 10 12 9 9 5 8 7 3 10 3 11 16 .

Parcours en largeur d’abord 0 2 1 2 3 4 4 8 5 6 8 10 12 9 9 5 6 7 7 10 3 11 17 ..

} } It´ratif et plus compliqu´ que le parcours en profondeur d’abord. FIFO f) { while ( !f. num[x] = -2.length. for (int ls = g.length). ++x) num[x] = -1. f). Breadth-First Search static void bfs (Graphe g. FIFO f = new FIFO (g. f).succ. f).succ.suivant) { int y = ls.val. num[y] = -2. num[x] = ++id.ajouter(x. } } } } static void visit (Graphe g) { id = -1.vide() ) { int x = FIFO. e e 18 . ls != null. for (int x = 0. x < g.supprimer (f).succ. bfs (g.ajouter(y. ++x) if (num[x] == -1) { FIFO. x < g.. for (int x = 0.succ[x]. if (num[y] == -1) { FIFO. Parcours en largeur d’abord. ls = ls.length.

Quelques probl`mes classiques e • Sortie de labyrinthe (dans un graphe non-orient´) e • Test de non-cyclicit´ dans un graphe orient´ e e • Tri topologique dans un graphe orient´ (Makefiles) e • Planarit´ (Tarjan) e • Connexit´ dans un graphe non orient´ e e • Plus court chemin • Coloriage de graphe • Optimisation de flot 19 ..

if (r != null) return new Liste (d. int s) { num[d] = ++id. } } return null. ls != null. null). r).. Exercice 2 Imprimer tous les chemins vers la sortie. ls = ls. x.val. Sortie de labyrinthe On cherche un chemin de d ` s. for (Liste ls = g. } Exercice 1 Calculer le chemin le plus court vers la sortie. 20 . if (num[x] == -1) { Liste r = chemin (g. if (d == s) return new Liste (d. a static Liste chemin (Graphe g. s). int d.suivant) { int x = ls.succ[d].

. existe-t-il 2 chemins diff´rents e e entre toute paire de noeuds? • Un point d’articulation est un point qui s´pare le graphe en e parties non connexes si on l’enl`ve. la e e topologie d’un r´seau informatique. la distribution d’´lectricit´. etc e 21 . Bi-connectivit´ e • Dans un graphe non orient´. • Exemples: les rues de Paris. e • Un graphe sans point d’articulation est un graphe bi-connexe.

val.. int min = id. } return min. ls != null.suivant) { int x = ls. } else if (num[x] < min) min = num[x]. for (Liste ls = g. ls = ls.succ[k]. Bi-connectivit´ e Un point d’attache de x est le plus petit y tel qu’un chemin relie x ` y contenant au plus un seul arc de retour z → z (tel que z > z ) a La fonction suivante (en dfs) calcule les points d’articulation. } 22 . if (num[x] == -1) { int m = attache (g. if (m < min) min = m. int k) { num[k] = ++id. static int attache (Graphe g. x). if (m >= num[k]) articulation[k] = true.

int r. static boolean[] articulation. x < n. } for (int x = 0. static int[] num. ++x) if (num[x] == -1) { r = attache(g. x < n. for (int x = 0.succ[x].. id = -1. static int id. Bi-connectivit´ – bis e Mais correction pour un noeud racine d’un arbre de recouvrement n’est articulation que s’il a au moins deux successeurs. articulation = new boolean[n]. if (articulation[x] && g.succ. ++x) { num[x] = -1. } } 23 .suivant == null) articulation[x] = false. num = new int[n]. articulation[x] = false.length. x). static void trouverArticulations (Graphe g) { int n = g.

e ee (Chemin ´l´mentaire ne passe pas deux fois par un mˆme ee e noeud). En TD – probl`mes e • Recherche de la plus courte sortie dans un labyrinthe • Recherche de la plus longue sortie dans un labyrinthe • Recherche de toutes les sorties dans un labyrinthe • Enum´rer tous les arbres de recouvrement e • Enum´rer tous les chemins (´l´mentaires) issus du noeud.. 24 .