Académique Documents
Professionnel Documents
Culture Documents
Département d'Informatique
Projet Module
Structure de données avancées
Spécialité : ISIL
Thème
Skip List
Réalisé par :
2020/2021
Sommaire
1 Introduction
2 Les algorithmes
2.1 La recherche
2.2 L’Insertion
2.3 La suppression
2.4 La hauteur
3 La complexité
1 Introduction
En informatique, il est courant de vouloir enregistrer des données
quelconques. Une structure de données est une représentation logique de ces
données. La manière de représenter les données permet de résoudre différents
problèmes. Une structure précise peut être plus performante pour un cas précis
ou, au contraire, être très peu performante. D’autre part, une meilleure
organisation de l’information peut aussi réduire de façon significative la
complexité d’un algorithme.
Il existe un grand nombre de structures de données, toutes proposent aux
concepteurs de logiciel deux fonctionnalités standard : enregistrer et récupérer
un renseignement. Selon l’approche employée pour la représentation logique, les
performances seront différentes. Certaines structures de données offrent la
possibilité de récupérer le premier élément en temps constant, au détriment du
temps d’accès aux autres éléments. Alors que d’autres permettent un accès en
temps constant à chacun des éléments en dépit d’une durée plus longue pour
l’enregistrement d’une information.
2 Les algorithmes
Une skip-List a besoin d’avoir un pointeur vers sa tête. La liste doit connaitre
le nombre de niveaux actuellement utilisés (level). Selon les implémentations, il
est possible de définir la hauteur maximale (levelMAX).
Il est aussi possible de changer le paramètre (p) de probabilité de création d’une
nouvelle couche. La variation de ces deux derniers paramètres est étudiée dans
le chapitre Analyse des performances. Un nœud contient une clé key, une valeur
value ainsi qu’un tableau de pointeur vers les nœuds suivants forward. Il n’est
pas nécessaire d’enregistrer la hauteur d’un nœud dans celui-ci.
2.1 La recherche
De manière générale, pour rechercher dans une Skip List il suffit de commencer
par le niveau le plus haut et d’effectuer une recherche élément par élément. Si
l’élément suivant devient plus grand que celui recherché, il suffit alors de des-
cendre d’un niveau dans la liste.
Algorithmique parlant, la recherche d’un élément s’exécute de la façon suivante:
On se place dans la première clé de la liste du haut
Tant qu’on peut descendre et qu’on n’a pas trouvé l’élément de clé k, on
exécute les opérations suivantes :
- On descend.
- Tant que la clé à droite est plus petite que k, on se déplace vers la droite.
2.2 L’Insertion
L’insertion d’une entrée dans une skip List est essentiellement la même
chose que la recherche. À l’exception qu’un tableau update, de taille identique à
la hauteur de la liste, est utilisé pour mémoriser les pointeurs de chaque élément
avant de descendre d’un niveau. Ce tableau est utilisé pour mettre à jour les liens
nécessaires pour que la structure de données reste cohérente.
Algorithmiquement parlant, l’insertion d’un élément dans une skip-List s’ef-
fectue de la façon suivante :
1. Commencer l’exploration de la liste par l’élément en tête, et se position-
ner sur la plus haute voie.
2. On joue à « pile ou face » jusqu’à ce que l’on obtienne « pile ». On dé-
note i le nombre de fois où on a eu « face » avant « pile ».
3. Si i >= h, on ajoute à la Skip Liste de nouvelles séquences « niveau ».
Chacune contenant seulement les éléments de clés spéciales +∞ et -∞.
Exemple : insérer un élément de clé 15, i=2 :
- On utilise l’algorithme chercher pour trouver les positions p des entrées
de plus grande clé plus petite ou égale à k dans chaque séquence S.
- Pour j = 0,….,i, on insère (k,v) dans Sj après la position Pj.
Figure : Insertion d’un élément
sxs
int skiplist_insert(skiplist *list, int key, int value)
{ snode *update[SKIPLIST_MAX_LEVEL+1];
snode *x = list->header; int i, level;
for (i = list->level; i >= 1; i--)
{ while (x->forward[i]->key < key)
x = x->forward[i];
update[i] = x; }
x = x->forward[1];
if (key == x->key)
{ x->value = value;
return 0;
} else {
level = rand_level();
if (level > list->level) {
for (i = list->level+1; i <= level; i++)
{ update[i] = list->header; }
list->level = level; }
x = (snode *)malloc(sizeof(snode));
x->key = key;
x->value = value;
x->forward = (snode **)malloc(sizeof(snode*) * (level + 1));
for (i = 1; i <= level; i++) {
x->forward[i] = update[i]->forward[i];
update[i]->forward[i] = x;}}
return 0;}
2.3 La suppression
La suppression d’un élément dans une skip-List s’effectue de la façon suivante :
1. On cherche dans la Skip List et on trouve les positions P d’une entrée
de clé k, ou la position Pj est dans le niveau Sj.
2. On enlève les éléments de positions p des niveaux S
3. On ne garde qu’une séquence ne contenant que les deux clés spéciales.
Exemple : Enlever 34 :
3 La complexité
Scénario Attendu Pire
Rechercher O(log n) O(n)
Insertion O(log n) O(n)
Suppression O(log n) O(n)