Quali sono le strutture dati meno conosciute ma utili?


795

Ci sono alcune strutture di dati che sono veramente utili ma che sono sconosciute alla maggior parte dei programmatori. Quali sono?

Tutti conoscono elenchi collegati, alberi binari e hash, ma per esempio elenchi Skip e filtri Bloom . Vorrei sapere più strutture di dati che non sono così comuni, ma vale la pena conoscerle perché si basano su grandi idee e arricchiscono la cassetta degli attrezzi di un programmatore.

PS: Sono anche interessato a tecniche come i collegamenti Dancing che fanno un uso intelligente delle proprietà di una struttura dati comune.

EDIT : prova a includere collegamenti a pagine che descrivono le strutture di dati in modo più dettagliato. Inoltre, prova ad aggiungere un paio di parole sul perché una struttura di dati è interessante (come già sottolineato da Jonas Kölker ). Inoltre, prova a fornire una struttura di dati per risposta . Ciò consentirà alle migliori strutture di dati di fluttuare in cima basandosi solo sui loro voti.


Risposte:


271

I tentativi , noti anche come alberi prefissi o alberi critici , esistono da oltre 40 anni ma sono ancora relativamente sconosciuti. Un uso molto interessante di try è descritto in " TRASH - Una struttura dinamica di dati LC-trie e hash ", che combina un trie con una funzione hash.


12
molto comunemente usato dai correttori ortografici
Steven A. Lowe,

I tentativi di burst sono anche una variante interessante, in cui si utilizza solo un prefisso delle stringhe come nodi e, in caso contrario, si memorizzano elenchi di stringhe nei nodi.
Torsten Marek,

Il motore regex in Perl 5.10 crea automaticamente tentativi.
Brad Gilbert,

Nella mia esperienza i tentativi sono dolorosamente costosi, dato che un puntatore è generalmente più lungo di un carattere, il che è un peccato. Sono adatti solo per determinati set di dati.
Joe

18
Dal momento che nessuna domanda SO, indipendentemente dall'argomento, è completa senza che qualcuno abbia menzionato jQuery .... John Resig, creatore di jQuery, ha un'interessante serie di post sulla struttura dei dati in cui esamina varie implementazioni di trie tra le altre: ejohn.org/blog/ revisionato-javascript-dizionario-ricerca
Oskar Austegard

231

Filtro Bloom : array di bit di m bit, inizialmente tutti impostati su 0.

Per aggiungere un oggetto, lo esegui attraverso k funzioni hash che ti daranno k indici nell'array che poi imposti a 1.

Per verificare se un elemento è nell'insieme, calcolare gli indici k e verificare che siano tutti impostati su 1.

Naturalmente, questo dà una certa probabilità di falsi positivi (secondo Wikipedia è circa 0,61 ^ (m / n) dove n è il numero di elementi inseriti). I falsi negativi non sono possibili.

La rimozione di un elemento è impossibile, ma è possibile implementare il filtro bloom di conteggio , rappresentato dalla matrice di ints e dall'incremento / decremento.


20
Dimentichi di menzionarne l'uso con i dizionari :) Puoi spremere un dizionario completo in un filtro bloom con circa 512k, come una tabella hash senza i valori
Chris S

8
Google cita l'uso dei filtri Bloom nell'implementazione di BigTable.
Brian Gianforcaro,

16
@FreshCode In realtà ti consente di testare a buon mercato l' assenza di un elemento nel set poiché puoi ottenere falsi positivi ma mai falsi negativi
Tom Savage

26
@FreshCode Come diceva @Tom Savage, è più utile per verificare la presenza di negativi. Ad esempio, puoi usarlo come un correttore ortografico veloce e piccolo (in termini di utilizzo della memoria). Aggiungi tutte le parole e prova a cercare le parole immesse dall'utente. Se ottieni un negativo significa che è scritto male. Quindi è possibile eseguire un controllo più costoso per trovare le corrispondenze più vicine e offrire correzioni.
Lacop,

5
@ abhin4v: i filtri Bloom vengono spesso utilizzati quando è probabile che la maggior parte delle richieste restituisca una risposta "no" (come nel caso qui), il che significa che il piccolo numero di risposte "sì" può essere verificato con un test esatto più lento. Ciò comporta comunque una notevole riduzione del tempo medio di risposta alla query. Non so se la Navigazione sicura di Chrome lo fa, ma sarebbe la mia ipotesi.
j_random_hacker,

140

Corda : è una stringa che consente anteprime, sottostringhe, inserzioni centrali e aggiunte a basso costo. L'ho usato solo una volta, ma nessun'altra struttura sarebbe stata sufficiente. Le anteprime regolari di stringhe e array erano semplicemente troppo costose per quello che dovevamo fare e invertire tutto era fuori discussione.


Ho pensato a qualcosa del genere per i miei usi. Bello sapere che è già stato implementato da qualche altra parte.
Kibbee,

15
C'è un'implementazione in SGI STL (1998): sgi.com/tech/stl/Rope.html
quark,

2
Senza sapere come si chiamava di recente ho scritto qualcosa di molto simile a questo per Java - le prestazioni sono state eccellenti: code.google.com/p/mikeralib/source/browse/trunk/Mikera/src/…
mikera

La corda è piuttosto rara: stackoverflow.com/questions/1863440/…
Will

6
Il link di Mikera è stantio, ecco l' attuale .
aptwebapps,

128

Le liste di salti sono piuttosto ordinate.

Wikipedia
Un skip list è una struttura di dati probabilistici, basata su più elenchi collegati paralleli e ordinati, con efficienza comparabile a un albero di ricerca binario (registro ordini n tempo medio per la maggior parte delle operazioni).

Possono essere usati come alternativa agli alberi bilanciati (usando il bilanciamento probalistico piuttosto che una rigorosa applicazione del bilanciamento). Sono facili da implementare e più veloci di quanto si pensi, un albero rosso-nero. Penso che dovrebbero essere in ogni buon programmatore toolchest.

Se si desidera ottenere un'introduzione approfondita alle liste di salto, ecco un collegamento a un video della lezione di Introduzione agli algoritmi del MIT su di essi.

Inoltre, ecco un'applet Java che mostra visivamente gli Skip List.


+1 Qt utilizza gli elenchi di salto anziché gli alberi RB per le mappe e i set ordinati. Sì, sono eleganti (in lingue imperative, comunque).
Michael Ekstrand,

2
Redis utilizza gli skip list per implementare "Set ordinati".
antirez,

Gli Skip List sono probabilmente la mia struttura di dati preferita da utilizzare quando ho bisogno di una buona struttura di dati e non ho garanzie riguardo all'ordine dei dati e voglio un'implementazione più semplice rispetto ad altre strutture di dati "bilanciate". Che bella cosa.
earino,

Nota a margine interessante: se aggiungi abbastanza livelli ai tuoi skip list, finirai essenzialmente con un albero a B.
Riyad Kalla,

92

Indici spaziale , in particolare R-alberi e KD-alberi , memorizzare dati spaziali in modo efficiente. Sono utili per i dati delle coordinate della mappa geografica e gli algoritmi di localizzazione e instradamento VLSI e talvolta per la ricerca del vicino più vicino.

Gli array di bit memorizzano i singoli bit in modo compatto e consentono operazioni di bit veloci.


6
Gli indici spaziali sono utili anche per le simulazioni del corpo N che coinvolgono forze a lungo raggio come la gravità.
Justin Peel,

87

Cerniere : derivate delle strutture dati che modificano la struttura per avere una nozione naturale di "cursore": posizione corrente. Questi sono davvero utili in quanto garantiscono che le indicazioni non possano essere fuori limite - utilizzate, ad esempio nel gestore delle finestre di xmonad per tenere traccia della finestra focalizzata.

Sorprendentemente, puoi ricavarli applicando tecniche dal calcolo al tipo di struttura dati originale!


2
questo è utile solo nella programmazione funzionale (nei linguaggi imperativi basta tenere un puntatore o un indice). Inoltre, non riesco ancora a capire come funzionano davvero le cerniere.
Stefan Monov,

4
@Stefan il punto è che non è necessario mantenere un indice o puntatore separato ora.
Don Stewart,

69

Eccone alcuni:

  • Suffix ci prova. Utile per quasi tutti i tipi di ricerca di stringhe (http://en.wikipedia.org/wiki/Suffix_trie#Functionality ). Vedi anche array di suffissi; non sono così veloci come gli alberi di suffisso, ma molto più piccoli.

  • Splay alberi (come menzionato sopra). Il motivo per cui sono fighi è triplice:

    • Sono piccoli: sono necessari solo i puntatori sinistro e destro come in qualsiasi albero binario (non è necessario memorizzare informazioni sul colore o sulla dimensione del nodo)
    • Sono (relativamente) molto facili da implementare
    • Offrono una complessità ammortizzata ottimale per tutta una serie di "criteri di misurazione" (il tempo di ricerca log è quello che tutti conoscono). Vederehttp://en.wikipedia.org/wiki/Splay_tree#Performance_theorems
  • Alberi di ricerca ordinati per heap: memorizzi un gruppo di coppie (chiave, prio) in un albero, in modo tale che sia un albero di ricerca rispetto alle chiavi e ordinato per heap rispetto alle priorità. Si può dimostrare che un tale albero ha una forma unica (e non è sempre completamente impacchettato verso l'alto e verso sinistra). Con priorità casuali, ti dà il tempo di ricerca O (log n) previsto, IIRC.

  • Una di nicchia sono gli elenchi di adiacenza per i grafici planari non indirizzati con le query O (1) vicine. Non si tratta tanto di una struttura di dati quanto di un modo particolare di organizzare una struttura di dati esistente. Ecco come lo fai: ogni grafico planare ha un nodo al massimo 6. Scegli un tale nodo, metti i suoi vicini nella sua lista vicina, rimuovilo dal grafico e ricicla fino a quando il grafico è vuoto. Quando viene data una coppia (u, v), cerca u nell'elenco dei vicini di v e nell'elenco v dei vicini di te. Entrambi hanno dimensioni al massimo di 6, quindi questo è O (1).

Con l'algoritmo sopra, se u e v sono vicini, non avrai sia tu nell'elenco v che l'elenco v. Se ne hai bisogno, aggiungi i vicini mancanti di ciascun nodo all'elenco dei vicini di quel nodo, ma archivia la quantità dell'elenco dei vicini che devi cercare per una ricerca rapida.


L'albero di ricerca ordinato dell'heap è chiamato treap. Un trucco che puoi fare con questi è cambiare la priorità di un nodo per spingerlo nella parte inferiore dell'albero dove è più facile eliminarlo.
paperhorse,

1
"L'albero di ricerca ordinato di Heap è chiamato un treap." - Nella definizione che ho sentito, IIRC, un passo falso è un albero di ricerca ordinato per heap con priorità casuali . Potresti scegliere altre priorità, a seconda dell'applicazione ...
Jonas Kölker,

2
Un trie di suffisso è quasi ma non esattamente lo stesso dell'albero del suffisso molto più fresco , che ha stringhe e non singole lettere sui suoi bordi e può essere costruito in tempo lineare (!). Inoltre, nonostante sia asintoticamente più lento, in pratica gli array di suffissi sono spesso molto più veloci degli alberi di suffisso per molte attività a causa delle loro dimensioni più ridotte e di un numero minore di riferimenti indiretti al puntatore. Adoro la ricerca del grafico planare O (1) BTW!
j_random_hacker,

@j_random_hacker: le matrici di suffissi non sono asintoticamente più lente. Ecco circa 50 righe di codice per la costruzione di array di suffissi lineari: cs.helsinki.fi/u/tpkarkka/publications/icalp03.pdf
Edward KMETT,

1
@Edward Kmett: ho infatti letto quel documento, è stata una vera svolta nella costruzione di array di suffissi . (Sebbene fosse già noto che la costruzione del tempo lineare era possibile andando "attraverso" un albero di suffisso, questo era il primo algoritmo "diretto" innegabilmente pratico.) Ma alcune operazioni al di fuori della costruzione sono ancora asintoticamente più lente su un array di suffissi a meno che un LCA viene anche creato un tavolo. Questo può essere fatto anche in O (n), ma in questo modo perdi i vantaggi di dimensioni e località dell'array di suffissi puri.
j_random_hacker il

65

Penso che le alternative senza blocco alle strutture di dati standard, ad esempio coda, stack ed elenco senza blocco, siano molto trascurate.
Sono sempre più rilevanti poiché la concorrenza diventa una priorità più elevata e sono obiettivi molto più ammirevoli rispetto all'utilizzo di mutex o blocchi per gestire le letture / scritture simultanee.

Ecco alcuni link
http://www.cl.cam.ac.uk/research/srg/netos/lock-free/
http://www.research.ibm.com/people/m/michael/podc-1996.pdf [Collegamenti a PDF]
http://www.boyet.com/Articles/LockfreeStack.html

Il blog (spesso provocatorio) di Mike Acton contiene alcuni articoli eccellenti sul design e gli approcci senza serratura


Le alternative prive di blocco sono così importanti nel mondo di oggi multi-core, molto parallelo, dipendente dalla scalabilità :-)
earino

Bene, un disgregatore in realtà fa un lavoro migliore nella maggior parte dei casi.
deadalnix,

55

Penso che Disjoint Set sia abbastanza elegante per i casi in cui è necessario dividere un gruppo di elementi in set distinti e richiedere l'appartenenza. Una buona attuazione dell'Unione e operazioni di Find comportano costi ammortizzati che sono effettivamente costanti (inverso della funzione di Ackermnan, se ricordo correttamente la mia classe di strutture di dati).


8
Questa è anche chiamata "struttura dei dati di unione-trova". Ero sbalordito quando ho appreso per la prima volta questa intelligente struttura di dati nella classe di algoritmi ...
BlueRaja - Danny Pflughoeft

le estensioni union-find-delete consentono anche un'eliminazione a tempo costante.
Peaker

4
Ho usato un Disjoint Set per il mio generatore Dungeon, per assicurarmi che tutte le stanze siano raggiungibili con passaggi :)
goldenratio

52

Mucchi di Fibonacci

Sono utilizzati in alcuni degli algoritmi più veloci conosciuti (asintoticamente) per molti problemi legati ai grafici, come il problema Percorso più breve. L'algoritmo di Dijkstra funziona nel tempo O (E log V) con heap binari standard; l'uso di heap di Fibonacci migliora quello di O (E + V log V), che è un enorme aumento di velocità per grafici densi. Sfortunatamente, però, hanno un alto fattore costante, che spesso li rende poco pratici.


Alto fattore costante come hai detto, e difficile da implementare bene secondo un amico che doveva. Fianally non è così bello, ma comunque, forse vale la pena conoscerlo.
p4bl0,

Questi ragazzi qui li hanno resi competitivi rispetto ad altri tipi di heap: cphstl.dk/Presentation/SEA2010/SEA-10.pdf C'è una struttura di dati correlati chiamata Pairing Heaps che è più facile da implementare e che offre prestazioni pratiche piuttosto buone. Tuttavia, l'analisi teorica è parzialmente aperta.
Manuel,

Dalla mia esperienza con i cumuli di Fibonacci, ho scoperto che il costoso funzionamento delle allocazioni di memoria lo rende meno efficiente di un semplice heap binario supportato da un array.
jutky

44

Chiunque abbia esperienza nel rendering 3D dovrebbe avere familiarità con gli alberi BSP . Generalmente, è il metodo strutturando una scena 3D per essere gestibile per il rendering conoscendo le coordinate e il rilevamento della telecamera.

Il partizionamento dello spazio binario (BSP) è un metodo per suddividere ricorsivamente uno spazio in insiemi convessi per iperpiani. Questa suddivisione dà origine a una rappresentazione della scena mediante una struttura di dati ad albero nota come albero BSP.

In altre parole, è un metodo per scomporre poligoni di forma complessa in insiemi convessi o poligoni più piccoli costituiti interamente da angoli non riflessi (angoli inferiori a 180 °). Per una descrizione più generale del partizionamento dello spazio, consultare Partizionamento dello spazio.

Inizialmente, questo approccio era stato proposto nella computer grafica 3D per aumentare l'efficienza di rendering. Alcune altre applicazioni includono l'esecuzione di operazioni geometriche con forme (geometria solida costruttiva) in CAD, rilevamento di collisioni in robotica e giochi per computer 3D e altre applicazioni informatiche che comportano la gestione di scene spaziali complesse.


... e relativi octrees e kd-alberi.
Lloeki,


38

Dai un'occhiata a Finger Trees , soprattutto se sei un fan delle strutture di dati puramente funzionali precedentemente menzionate . Sono una rappresentazione funzionale di sequenze persistenti che supportano l'accesso alle estremità in tempo costante ammortizzato e la concatenazione e la divisione nel tempo logaritmica nella dimensione del pezzo più piccolo.

Secondo l'articolo originale :

I nostri alberi funzionali a 2-3 dita sono un'istanza di una tecnica di progettazione generale introdotta da Okasaki (1998), chiamata rallentamento ricorsivo implicito . Abbiamo già notato che questi alberi sono un'estensione della sua struttura di deque implicita, sostituendo le coppie con 2-3 nodi per fornire la flessibilità richiesta per concatenazione e divisione efficienti.

Un albero delle dita può essere parametrizzato con un monoide e l'uso di diversi monoidi comporterà comportamenti diversi per l'albero. Ciò consente a Finger Trees di simulare altre strutture di dati.



Dai un'occhiata a questa risposta duplicata , vale la pena leggere!
Francois G,

34

Buffer circolare o ad anello - utilizzato per lo streaming, tra le altre cose.


4
Inoltre, disgustosamente, in qualche modo è riuscito a essere brevettato (almeno quando usato per i video). ip.com/patent/USRE36801
David Eison,

Basandomi sulla lettura del link, non credo che la struttura stessa dei dati sia brevettata, ma alcune invenzioni basate su di esso. Concordo sul fatto che questa è sicuramente una struttura di dati molto poco utilizzata.
Gravità il

33

Sono sorpreso che nessuno abbia menzionato alberi di Merkle (es. Hash Trees ).

Utilizzato in molti casi (programmi P2P, firme digitali) in cui si desidera verificare l'hash di un intero file quando si dispone solo di una parte del file disponibile.


32

<zvrba> Alberi di Van Emde-Boas

Penso che sarebbe utile saperlo perché sono fighi. In generale, la domanda "perché" è la più importante da porre;)

La mia risposta è che ti danno dizionari O (log log n) con {1..n} chiavi, indipendentemente da quante chiavi sono in uso. Proprio come il dimezzamento ripetuto ti dà O (log n), lo sqrting ripetuto ti dà O (log log n), che è ciò che accade nell'albero vEB.


Sono carini da un punto di vista teorico. In pratica, tuttavia, è abbastanza difficile ottenere prestazioni competitive da loro. Il documento che conosco li ha portati a funzionare bene fino a 32 bit ( citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.7403 ) ma l'approccio non si ridimensionerà a più di forse 34-35 bit o così e non vi è alcuna implementazione di questo.
Manuel,

Un altro motivo per cui sono interessanti è che sono un elemento chiave per una serie di algoritmi ignari della cache.
Edward KMETT,


29

Una variante interessante della tabella hash si chiama Cuckoo Hashing . Utilizza più funzioni hash anziché solo 1 per gestire le collisioni hash. Le collisioni vengono risolte rimuovendo il vecchio oggetto dalla posizione specificata dall'hash primario e spostandolo in una posizione specificata da una funzione hash alternativa. Cuckoo Hashing consente un uso più efficiente dello spazio di memoria perché puoi aumentare il fattore di carico fino al 91% con solo 3 funzioni di hash e avere comunque un buon tempo di accesso.


5
Controlla che l'hashing di campana sia più veloce.
Chmike,

27

Un heap min-max è una variazione di un heap che implementa una coda di priorità doppia. Ciò si ottiene modificando semplicemente la proprietà heap: si dice che un albero è ordinato min-max se ogni elemento su livelli pari (dispari) è meno (maggiore) di tutti i bambini e nipoti. I livelli sono numerati a partire da 1.

http://internet512.chonbuk.ac.kr/datastructure/heap/img/heap8.jpg


Difficile da implementare. Anche i migliori programmatori possono sbagliare.
finnw,

26

Mi piacciono le datastructures Cache Oblivious . L'idea di base è quella di disporre un albero in blocchi ricorsivamente più piccoli in modo che le cache di molte dimensioni diverse trarranno vantaggio da blocchi che si adattano comodamente in essi. Ciò porta a un uso efficiente della cache in qualsiasi cosa, dalla cache L1 nella RAM a grandi blocchi di dati letti dal disco senza dover conoscere le specifiche delle dimensioni di nessuno di quei livelli di cache.


Interessante trascrizione da quel link: "La chiave è il layout di Van Emde Boas, che prende il nome dalla struttura dei dati dell'albero di Van Emde Boas ideata nel 1977 da Peter van Emde Boas"
sergiol

23

Alberi pendenti rosso-neri pendenti a sinistra . Un'implementazione significativamente semplificata di alberi rosso-neri di Robert Sedgewick pubblicata nel 2008 (~ metà delle righe di codice da implementare). Se hai mai avuto problemi a avvolgere la testa attorno all'implementazione di un albero rosso-nero, leggi questa variante.

Molto simile (se non identico) agli alberi di Andersson.



19

Cumuli binomiali obliqui di Bootstrap di Gerth Stølting Brodal e Chris Okasaki:

Nonostante il loro lungo nome, forniscono operazioni heap asintoticamente ottimali, anche in un'impostazione di funzione.

  • O(1)dimensioni, unione , inserto, minimo
  • O(log n) deleteMin

Si noti che l'unione richiede O(1)più del O(log n)tempo, diversamente dai mucchi più noti che sono comunemente trattati nei libri di testo della struttura dei dati, come i mucchi di sinistra . E a differenza dei cumuli di Fibonacci , quegli asintotici sono nel peggiore dei casi, piuttosto che ammortizzati, anche se usati in modo persistente!

Esistono molteplici implementazioni in Haskell.

Furono derivati ​​congiuntamente da Brodal e Okasaki, dopo che Brodal inventò un mucchio imperativo con gli stessi asintotici.


18
  • Kd-Trees , la struttura dei dati spaziali utilizzata (tra gli altri) in Real-Time Raytracing, ha il rovescio della medaglia che i triangoli che si intersecano tra loro intersecano i diversi spazi devono essere ritagliati. Generalmente i BVH sono più veloci perché sono più leggeri.
  • MX-CIF Quadtrees , memorizza i rettangoli anziché i set di punti arbitrari combinando un quadrifoglio regolare con un albero binario ai bordi dei quadricipiti.
  • HAMT , mappa gerarchica di hash con tempi di accesso che generalmente superano O (1) hash-map a causa delle costanti coinvolte.
  • Indice invertito , abbastanza noto nei circoli dei motori di ricerca, perché viene utilizzato per il recupero rapido di documenti associati a termini di ricerca diversi.

La maggior parte, se non tutte, di queste sono documentate nel Dizionario NIST di algoritmi e strutture dati



17

Non proprio una struttura di dati; più un modo per ottimizzare gli array allocati dinamicamente, ma i buffer di gap utilizzati in Emacs sono piuttosto interessanti .


1
Lo considererei sicuramente una struttura di dati.
Christopher Barber,

Per chiunque sia interessato, questo è esattamente il modo in cui vengono implementati anche i modelli Document (es. PlainDocument) che supportano i componenti di testo Swing; prima della 1.2 credo che i modelli di documento fossero schiere diritte, che portavano a prestazioni di inserimento orribili per documenti di grandi dimensioni; non appena si sono trasferiti ai Gap Buffer, tutto è andato di nuovo bene nel mondo.
Riyad Kalla,

16

Albero di Fenwick. È una struttura di dati per tenere conto della somma di tutti gli elementi in un vettore, tra due sottoindici i e j. La soluzione banale, precalcolando la somma poiché l'inizio non consente di aggiornare un elemento (devi fare O (n) lavoro per tenere il passo).

Gli alberi Fenwick ti consentono di aggiornare e interrogare in O (log n), e come funziona è davvero semplice e interessante. È davvero ben spiegato nel documento originale di Fenwick, disponibile gratuitamente qui:

http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol24/issue3/spe884.pdf

Suo padre, l'albero RQM è anche molto bello: ti permette di mantenere informazioni sull'elemento minimo tra due indici del vettore e funziona anche con O (log n) update e query. Mi piace insegnare prima l'RQM e poi l'albero di Fenwick.


Temo che questo sia un duplicato . Forse vorresti aggiungere alla risposta precedente?
Francois G,

Inoltre sono correlati gli alberi dei segmenti, utili per eseguire tutti i tipi di query sull'intervallo.
Dhruvbird,


13

Gli insiemi nidificati sono utili per rappresentare alberi nei database relazionali ed eseguire query su di essi. Ad esempio, ActiveRecord (ORM predefinito di Ruby on Rails) viene fornito con un plug-in set nidificato molto semplice , che lavoro con gli alberi.


12

È piuttosto specifico per il dominio, ma la struttura dei dati semi-edge è piuttosto ordinata. Fornisce un modo per scorrere le mesh poligonali (facce e bordi), molto utile nella computer grafica e nella geometria computazionale.

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.