Per coincidenza, in realtà ho appena implementato un btree in C#, per un progetto personale. È stato divertente. Ho creato un insieme di chiavi di dimensioni variabili (fino a 64 byte) con ordine lessicografico che hanno presentato una serie di difficoltà, in particolare per capire quando una pagina di archiviazione era troppo piena o troppo vuota.
Il mio consiglio, avendo appena finito, è di costruire un livello di astrazione che cattura solo gli algoritmi btree nella loro forma più astratta, come una classe base astratta. Una volta ottenute tutte le regole btree catturate in quella forma, ho specializzato la classe base in molti modi diversi: come un normale 2-3-size a dimensione fissa, come una delle mie fantasiose chiavi a dimensione variabile, e così via .
Per iniziare, in nessun caso si dovrebbe fare questo con i puntatori. Il codice non sicuro è raramente necessario e mai facile. Solo i programmatori C# più avanzati dovrebbero spegnere il sistema di sicurezza; quando lo fai, ti stai assumendo la responsabilità per il tipo e la sicurezza della memoria del programma. Se non si è disposti a farlo, lasciare il sistema di sicurezza acceso.
In secondo luogo, non c'è motivo di rendere questa struttura. Le strutture vengono copiate in base al valore in C#; un nodo btree non è un valore .
In terzo luogo, non è necessario mantenere il numero di chiavi in un nodo; l'array di chiavi sa quante chiavi ci sono dentro.
In quarto luogo, vorrei usare un List<T>
piuttosto che un array; sono più flessibili.
Quinto, è necessario decidere se la vita chiave del nodo o nella genitore. Ad ogni modo può funzionare; la mia preferenza è che la chiave viva nel nodo, perché vedo la chiave associata al nodo.
In sesto luogo, è utile sapere se un nodo btree è o meno root; potresti considerare di avere due bool, uno "è questa una foglia?" e uno "è questa la radice?" Ovviamente un btree con un singolo oggetto contiene un singolo nodo che è sia foglia che radice.
Settimo, probabilmente costruirai questa cosa per essere mutabile; normalmente non si rendono pubblici i campi mutabili su una classe C#. Potresti considerare di renderle proprietà. Inoltre, la lista dei figli può essere coltivato e ristretto, ma la sua identità non cambia, in modo da renderlo referenzialmente sola lettura:
Così ho probabilmente strutturare il mio nodo di base come:
class Node
{
public int Key { get; set; }
public bool IsRoot { get; set; }
public bool IsLeaf { get; set; }
private List<Node> children = new List<Node>();
public List<Node> Children { get { return this.children; } }
}
Ha senso?
Perché si desidera utilizzare una struct anziché una classe? – CodesInChaos
ovviamente puoi usare C# per gli alberi B – Adrian
Non provare a usare codice non sicuro in C# finché non sei un esperto; ti sbagli e sarà doloroso e difficile. Piuttosto, impara prima il modo sicuro di fare le cose; C# è progettato in modo che il modo sicuro di fare le cose sia quasi sempre più facile del modo pericoloso. –