Les tables

Transcription

Les tables
Quelques structures de données utiles
Listes;
Tables: tables de hachage, arbres équilibrés, hash-tries;
1
Les listes
En Caml, la liste [1; 2; 3] est juste la paire formée de et de (la paire
formée de 2 et de (la paire formée de 3 et de la liste vide nil)).
(* [1; 2; 3] = cons (1, cons (2, cons (3, nil))) *)
type ’a list = nil | cons of ’a * ’a list;;
let hd x = match x with cons (y, _) -> y;;
let tl x = match x with cons (_, l) -> l;;
let isnull x = match x with nil -> true | _ -> false;;
nil
1
2
3
2
Les tables
But: représenter des fonctions partielles. Par exemple, une table qui à
chaque nom de variable associe le code qu’il faut compiler pour obtenir sa
valeur.
On veut donc:
type key type val type table (* = table key -> val *);;
exception Not_found;;
val find : key -> table -> val
(* lance Not_found si pas dans le domaine *);;
val add : key -> val -> table -> table;;
val empty : table;
...
3
Tables: 1. Listes d’associations
type table = (key * val) list;;
let rec find k t = match t with
nil -> raise Not_found
| cons ((k’, v’), r) ->
if k=k’ then v’ else find k r;;
let rec add k v t = (k, v)::t;;
let empty = [];;
Facile... mais peu efficace.
Exercice: quelle est la complexité de find?
4
Tables: 2. Tables de hachage
Idée:
(son hash-code);
1. calculer pour chaque clé (key) un numéro de à
2. faire un tableau de listes d’associations, une pour chaque hash-code.
Par ex:
let rec hash (s : string) (n : int) : int =
let h = ref 0 in
for i = 0 to String.length s-1 do
h := !h + Char.code (String.get s i)
done;
!h mod n;;
5
nil
nil
nil
nil
nil
nil
nil
nil
9
nil
valeur
"abc"
nil
nil
nil
17
valeur
"toto"
6
Complexité de find: toujours
, où
... mais la constante mulfois moins grande que
tiplicative est
pour les listes d’associations.
Exercice: écrire les fonctions find, add,
empty. Noter que add modifie la table de
hachage, contrairement à la spécification
de départ, qui demandait de construire une
nouvelle table.
Note: il y a bien d’autres algorithmes de
hachage, cf. D. Knuth, The Art of Computer Programming, vol.1. En OCaml,
utiliser le module Hashtbl.
nil
Tables: 3. Arbres équilibrés
Précurseur: les arbres AVL (Avelson, Vel’skii, Landis). Bien d’autres:
arbres rouge-noir, B, B*, etc.
Avantages: purement applicatifs: add ne modifie pas la table, mais en crée
une nouvelle — comme spécifié.
Prérequis: nécessite un ordre total sur les clés key.
Note: réalisés dans le module Caml Map.
7
Les arbres équilibrés: idée générale
La complexité de find est proportionnelle
à la hauteur de l’arbre.
Pour un arbre binaire, la hauteur de l’arbre
où est le cardinal de la
est
table.
Les arbres AVL maintiennent la hauteur de
, ce qui est essenl’arbre à
tiellement optimal.
8
"abc"
nil
"toto"
Les arbres AVL: structure
Les paires (clé, valeur) sont stockées aux nœuds, pas juste aux feuilles.
Chaque nœud contient une clé, une valeur, un sous-arbre gauche, un
sous-arbre droit.
, toute clé de est
, et
Invariant: dans tout nœud
toute clé de .
De plus, on maintient dans chaque nœud la différence entre les hauteurs des
deux sous-arbres.
On va définir une opération d’équilibrage, qui ramène ces différences entre
et , tout en préservant l’invariant.
type avl = VIDE
| AVL of key * val * avl * avl * int;;
9
Équilibrage des arbres AVL: rotation simple
2
1
1
C
B
A
2
A
B
C
Exercice: en supposant que l’arbre de gauche n’est pas équilibré, au sens
où le sous-arbre de gauche ( , , ) a une hauteur supérieure ou égale à
plus la hauteur de , sous quelles conditions la réécriture ci-dessus fait-elle
diminuer le défaut d’équilibrage?
10
Équilibrage des arbres AVL: rotation double
2
1
1
A
3
B
C
3
A
2
D
B
D
C
Exercice: montrer que lorsque la rotation simple ne fait pas diminuer le
défaut d’équilibrage, la rotation double (ci-dessus) le fait.
, où
11
Exercice: en déduire comment coder find, add, en temps
est le cardinal de la table.
Tables: 4. les arbres “hash-trie”
Beaucoup plus simples!
Couples clés, valeurs stockés aux feuilles, pas aux nœuds.
complexité pas bornée!
Pas équilibrés
en moyenne.
Par contre, complexité de find
de hachage parfaite
Petit inconvénient: nécessite une fonction
).
(
type trie = VIDE
| SINGLETON of key * val
| BRANCH of trie * trie;;
12
Les hash-tries: normalisation
Pour find k t, calculer k , l’écrire
en binaire; descendre à gauche pour
chaque bit à , à droite pour chaque bit à
.
1
Invariant: tout sous-nœud BRANCH conSINGLETON
tient au moins deux clés.
1
"toto"
Exercice: montrer que la représentation
hash−code 00110101
VIDE
de fonctions de domaine fini sous forme
de hash-tries est canonique si l’invariant
est respecté: il existe un hash-trie exactement ( étant fixé) représentant une table
donnée.
0
BRANCH
0
SINGLETON
"abc"
hash−code 01101000
13
BRANCH
Les hash-tries: complexité
Exercice: en supposant que k est une suite de bits uniformément
distribuée, montrer que la hauteur moyenne d’un hash-trie représentant une
plus une petite constante.
table de cardinal est
Montrer que la taille de cette hash-trie est
.
Exercice: coder find, add. Montrer que la complexité moyenne est
. De quel ordre est l’écart-type de la complexité? (Indication: il est
extrêmement faible.)
14

Documents pareils