Esiste una struttura di dati per la manipolazione rapida dell'elenco e le richieste di ordini?


9

Abbiamo un insieme, , di elenchi di elementi dell'insieme . Ogni elemento da appare in un singolo elenco . Sto cercando una struttura di dati in grado di eseguire i seguenti aggiornamenti:N = { 1 , 2 , 3 , . . . , n } N LLN={1,2,3,...,n}NL

  1. concun't(X,y) : concatena l'elenco contenente alla fine dell'elenco contenentexyX

  2. Spliot(X) : divide l'elenco contenente direttamente dopoxXX

Deve inoltre eseguire le seguenti query:

  1. followS(X,y) : restituisce se ed sono nella stessa lista e viene dopo (ma non è necessariamente adiacente )x y y x xtrueXyyXX

  2. fiorSt(X) : restituisce il primo elemento dell'elenco contenenteX

  3. neXt(X) : restituisce l'elemento successivo dopo nell'elenco contenentexXX

Ho già creato una struttura di dati che esegue questi aggiornamenti in e le query in . Sono principalmente interessato a sapere se esiste già una struttura di dati che può farlo (si spera più velocemente?).O ( l g ( n ) )O(lg2(n))O(lg(n))

Motivazione: le foreste dirette radicate possono essere rappresentate con due di questi insiemi di elenchi e consentono un rapido calcolo della raggiungibilità in tali foreste. Voglio vedere per cos'altro possono essere utilizzati e se tutto questo è già noto.

Risposte:


11

Mantieni i tuoi numeri interi negli elenchi di salto. Le liste di salto normali sono ordinate per chiave, ma le useremo semplicemente come rappresentazione di sequenze. Inoltre, mantenere un array di puntatori di dimensione . Ogni elemento dell'array deve puntare a un nodo in un elenco di salto. Credo che questo supporti il in e tutte le altre operazioni in .n e x t O ( 1 ) O ( lg n )nnextO(1)O(lgn)

In particolare:

  • s p l i t O ( lg n ) O ( lg n )concat o due skip list richiede tempo e pertanto invalida al massimo i puntatori .splitO(lgn)O(lgn)
  • O ( 1 )next segue semplicemente il puntatore in avanti a livello foglia, impiegando tempo.O(1)
  • firstrichiede tempo: segui i puntatori fino a quando non rimani bloccato, quindi segui un puntatore a sinistra. Quando non puoi più seguire i puntatori a sinistra, sei nel puntatore principale del tuo elenco di salti. Segui i puntatori verso il basso sulla foglia, quindi un puntatore in avanti. Questo è il primo elemento nell'elenco.O(lgn)
  • follows è un po 'più complicato. Procedere come nella per la , ma registrare un elenco dei valori in cui ti trovi in difficoltà (cioè, dove non è possibile seguire i puntatori più). Chiameremo questo elenco per registrare una "traccia". Fai lo stesso per , ma segui i puntatori a destra quando rimani bloccato, non a sinistra. Se precede , le loro tracce si intersecano. Le tracce sono di dimensione . Se ogni elemento nella traccia è annotato con il livello bloccato, possiamo verificare un'intersezione nel tempo .firstyxxyO(lgn)O(lgn)

next è il caso peggiore , tutti gli altri sono con alta probabilità . Possono essere fatti nel peggiore dei casi usando gli skip list deterministici.O(1)O(lgn)

Penso che possa essere fatto usando alberi collegati a livello fogliare (2,5) e raccogliendo le spine. Per il trucco del bootstrap, vedi " Rappresentazioni puramente funzionali di elenchi ordinati catenabili " di Kaplan e Tarjan.O ( lg lg n )concatO(lglgn)


freddo. Stavo pensando di saltare gli elenchi ma non riuscivo a vedere come seguire senza i valori chiave associati.
Sasho Nikolov,

Questo è fantastico; Vedo come rendere deterministici tutti gli aggiornamenti , il che è positivo. Dovrò continuare a leggere per capire la O (lg lg (n)). Grazie per il post @jbapple. O(lg(n))
bbejot,

1

Il problema meno comune degli antenati può essere utilizzato per risolvere il problema della raggiungibilità negli alberi con radici dinamici, quindi immagino che anche tu sarai interessato a quanto segue: Algoritmi ottimali per la ricerca di antenati comuni più vicini negli alberi dinamici , di Alstrup e Thorup. Questo documento fornisce un limite di tempo di per n collegamenti e m nca query su una macchina puntatore. O(n+mloglogn)nm


grazie per il riferimento. Il problema antenato comune più vicino risolve certamente la raggiungibilità negli alberi. La carta a cui hai collegato descrive un albero incrementale con tutte le operazioni in tempo . Mi chiedo se possa essere migliorato anche con alberi completamente dinamici. O(lglg(n))
bbejot,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.