Eu estava procurando uma estrutura de dados em árvore ou gráfico em C #, mas acho que não há uma fornecida. Um exame abrangente das estruturas de dados usando o C # 2.0 explica um pouco sobre o porquê. Existe uma biblioteca conveniente que é comumente usada para fornecer essa funcionalidade? Talvez através de um padrão de estratégia para resolver os problemas apresentados no artigo.
Sinto-me um pouco tolo ao implementar minha própria árvore, assim como implementaria minha própria ArrayList.
Eu só quero uma árvore genérica que pode ser desequilibrada. Pense em uma árvore de diretórios. O C5 parece bacana, mas suas estruturas de árvore parecem ser implementadas como árvores vermelho-preto equilibradas, mais adequadas para pesquisar do que representar uma hierarquia de nós.
fonte
Respostas:
Meu melhor conselho seria que não exista uma estrutura de dados em árvore padrão, porque há tantas maneiras de implementá-la que seria impossível cobrir todas as bases com uma solução. Quanto mais específica uma solução, menor a probabilidade de ela ser aplicável a qualquer problema. Eu até me irrito com o LinkedList - e se eu quiser uma lista circular vinculada?
A estrutura básica que você precisará implementar será uma coleção de nós e aqui estão algumas opções para você começar. Vamos supor que a classe Node seja a classe base de toda a solução.
Se você precisar navegar apenas pela árvore, uma classe Node precisará de uma Lista de filhos.
Se você precisar navegar na árvore, a classe Node precisará de um link para seu nó pai.
Crie um método AddChild que cuide de todas as minúcias desses dois pontos e de qualquer outra lógica comercial que deva ser implementada (limites de filhos, classificação dos filhos etc.)
fonte
Implementação recursiva simples ... <40 linhas de código ... Você só precisa manter uma referência à raiz da árvore fora da classe ou agrupá-la em outra classe, talvez renomear para TreeNode ??
fonte
Action<T>
delegado:public void traverse(NTree<T> node, Action<T> visitor)
. Action <> 's assinatura é:void Action<T>( T obj )
. Existem também versões de 0 a 4 parâmetros diferentes. Há também um delegado análogo para funções chamadasFunc<>
.--i == 0
funcionará apenas em caso único? Isso é verdade. Isso fez-me confundemAqui está o meu, que é muito semelhante ao de Aaron Gage , um pouco mais convencional, na minha opinião. Para meus propósitos, não tive problemas com desempenho
List<T>
. Seria fácil mudar para um LinkedList, se necessário.fonte
public TreeNode<T> InsertChild(TreeNode<T> parent, T value) { var node = new TreeNode<T>(value) { Parent = parent }; parent._children.Add(node); return node; }
var five = myTree.AddChild(5); myTree.InsertChild(five, 55);
Ainda outra estrutura de árvore:
Uso da amostra:
BÔNUS
Veja a árvore de pleno direito com:
https://github.com/gt4dev/yet-another-tree-structure
fonte
node
vem? Isso significa que eu tenho que percorrer a árvore para usar o código de pesquisa?IEnumerable<>
membros, por isso não compila.A geralmente excelente biblioteca de coleções genéricas C5 possui várias estruturas de dados baseadas em árvore, incluindo conjuntos, malas e dicionários. O código-fonte está disponível se você deseja estudar os detalhes de implementação. (Usei coleções C5 no código de produção com bons resultados, embora não tenha usado nenhuma das estruturas em árvore especificamente.)
fonte
Consulte http://quickgraph.codeplex.com/
O QuickGraph fornece estruturas de dados e algoritmos genéricos de gráficos direcionados / não direcionados para .Net 2.0 e superior. O QuickGraph vem com algoritmos como profundidade na primeira busca, respiração na primeira busca, busca A *, caminho mais curto, caminho mais curto k, fluxo máximo, árvore de abrangência mínima, ancestrais menos comuns, etc. renderize os gráficos, serialize para GraphML, etc ...
fonte
Se você quiser escrever o seu próprio, pode começar com este documento de seis partes detalhando o uso efetivo das estruturas de dados do C # 2.0 e como analisar a implementação das estruturas de dados no C #. Cada artigo tem exemplos e um instalador com amostras que você pode acompanhar.
“Um exame abrangente das estruturas de dados usando o C # 2.0” por Scott Mitchell
fonte
Eu tenho uma pequena extensão para as soluções.
Usando uma declaração genérica recursiva e uma subclasse derivada, você pode se concentrar melhor no seu destino real.
Observe que é diferente de uma implementação não genérica; você não precisa converter 'node' no 'NodeWorker'.
Aqui está o meu exemplo:
fonte
Aqui está o meu:
Resultado:
fonte
Experimente este exemplo simples.
fonte
Crio uma classe Node que pode ser útil para outras pessoas. A classe possui propriedades como:
Também há a possibilidade de converter uma lista simples de itens com um ID e um ParentId em uma árvore. Os nós mantêm uma referência para os filhos e o pai, o que torna os nós iterativos bastante rápidos.
fonte
Como não foi mencionado, gostaria que você chamasse a atenção para a base de código .net agora lançada: especificamente o código de um
SortedSet
que implementa uma árvore Red-Black-Tree:https://github.com/Microsoft/referencesource/blob/master/System/compmod/system/collections/generic/sortedset.cs
Esta é, no entanto, uma estrutura de árvore equilibrada. Portanto, minha resposta é mais uma referência ao que acredito ser a única estrutura de árvore nativa na biblioteca principal .net.
fonte
Concluí o código que @Berezh compartilhou.
fonte
Aqui está uma árvore
Você pode até usar inicializadores:
fonte
A maioria das árvores é formada pelos dados que você está processando.
Outro exemplo é uma árvore de análise em um compilador…
O que os dois exemplos mostram é que o conceito de uma árvore faz parte do domínio dos dados e o uso de uma árvore de uso geral separada pelo menos duplica o número de objetos criados, além de dificultar a programação da API.
O que queremos é uma maneira de reutilizar as operações em árvore padrão, sem ter que reimplementá-las para todas as árvores, enquanto, ao mesmo tempo, não é necessário usar uma classe de árvore padrão. O Boost tentou resolver esse tipo de problema para C ++, mas ainda não vi nenhum efeito para o .NET se adaptar.
fonte
Adicionei solução completa e exemplo usando a classe NTree acima, também adicionei o método "AddChild" ...
usando
fonte
Aqui está a minha implementação do BST
fonte
Se você deseja exibir essa árvore na GUI, pode usar o TreeView e o TreeNode . (Suponho que tecnicamente você pode criar um TreeNode sem colocá-lo em uma GUI, mas ele tem mais sobrecarga do que uma simples implementação doméstica do TreeNode.)
fonte
Caso você precise de uma implementação de estrutura de dados em árvore com raiz que use menos memória, você pode gravar sua classe Node da seguinte maneira (implementação em C ++):
fonte