Existe-t-il une structure de données pour la manipulation rapide des listes et les requêtes de commande?


9

Nous avons un ensemble, , de listes d'éléments de l'ensemble . Chaque élément de apparaît dans une liste unique en . Je recherche une structure de données pouvant effectuer les mises à jour suivantes:N = { 1 , 2 , 3 , . . . , n }LN={1,2,3,...,n}NL

  1. concat(x,y) : concatène la liste contenant à la fin de la liste contenantyx

  2. split(x) : divise la liste contenant directement aprèsxx

Il doit également effectuer les requêtes suivantes:

  1. follows(x,y) : retourne si et sont dans la même liste et vient après (mais n'est pas nécessairement adjacent à )truexyyxx

  2. first(x) : retourne le premier élément de la liste contenantx

  3. next(x) : renvoie l'élément suivant après dans la liste contenantxx

J'ai déjà trouvé une structure de données qui effectue ces mises à jour en et les requêtes en O (lg (n)) . Je suis surtout intéressé à savoir s'il existe déjà une structure de données qui peut le faire (je l'espère plus rapide?)O(lg2(n))O(lg(n))

Motivation: les forêts dirigées enracinées peuvent être représentées avec deux de ces ensembles de listes et elles permettent un calcul rapide de l'accessibilité dans ces forêts. Je veux voir à quoi d'autre ils peuvent servir et si tout cela est déjà connu.

Réponses:


11

Conservez vos entiers dans les listes à sauter. Les listes de saut normales sont classées par clé, mais nous les utiliserons simplement comme représentation de séquences. En outre, conservez un tableau de pointeurs de taille . Chaque élément du tableau doit pointer vers un nœud dans une liste à sauter. Je crois que cela prend en charge dans et toutes les autres opérations dans .nnextO(1)O(lgn)

Plus précisément:

  • concat ou deux listes de sauts prend du temps et invalide donc au plus pointeurs.splitO(lgn)O(lgn)
  • next suit simplement le pointeur avant au niveau de la feuille, en prenant .O(1)
  • firstprend d' : suivez les pointeurs jusqu'à ce que vous soyez bloqué, puis suivez un pointeur gauche. Lorsque vous ne pouvez plus suivre les pointeurs de gauche, vous êtes au premier pointeur de votre liste de sauts. Suivez les pointeurs vers le bas de la feuille, puis un pointeur vers l'avant. Il s'agit du premier élément de la liste.O(lgn)
  • follows est un peu plus délicat. Procédez comme en pour , mais enregistrez une liste des valeurs où vous êtes bloqué (c'est-à-dire où vous ne pouvez plus suivre les pointeurs). Nous appellerons cette liste vous enregistrez une "trace". Faites de même pour , mais suivez les pointeurs de droite lorsque vous êtes coincé, pas à gauche. Si précède , leurs traces se croiseront. Les traces sont de taille . Si chaque élément de la trace est annoté avec le niveau bloqué, nous pouvons vérifier une intersection dans le temps .firstyxxyO(lgn)O(lgn)

next pire des cas , tous les autres sont avec une probabilité élevée . Ils peuvent être rendus dans le pire des cas en utilisant des listes de saut déterministes.O(1)O(lgn)

Je pense que la peut être faite en utilisant des arbres liés au niveau des feuilles (2,5) et en renforçant les épines. Pour l'astuce d'amorçage, voir " Représentations purement fonctionnelles de listes triées caténables " par Kaplan et Tarjan.concatO(lglgn)


cool. Je pensais à sauter des listes mais je ne pouvais pas vraiment voir comment suivre sans valeurs de clé associées.
Sasho Nikolov

C'est bien; Je vois comment faire toutes les mises à jour déterministes , ce qui est bien. Je vais devoir continuer à lire pour comprendre le O (lg lg (n)). Merci pour le post @jbapple. O(lg(n))
bbejot

1

Le problème d' ancêtre le moins courant peut être utilisé pour résoudre le problème d'accessibilité dans les arbres enracinés dynamiques, donc j'imagine que vous serez également intéressé par les éléments suivants: Algorithmes optimaux pour trouver les ancêtres communs les plus proches dans les arbres dynamiques , par Alstrup et Thorup. Cet article donne une limite de temps de pour n liens et m nca requêtes sur une machine à pointeur. O(n+mloglogn)nm


O(lglg(n))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.