製品カタログをツリー形式で作成する必要があります。
すべてのツリーノードはID(string)で表され、ツリーデータの関数は2のみです。
getChild(string ID)
、IDの提供、子の取得(子の子を含める必要はありません)、IDがnullの場合、すべてのルートノードの取得getParent(string ID)
、持っている場合は親IDを返し、ルートの場合はnullを返します一度ツリーが決定すると、変更されないので、すべてのコードを静的に配置するのが最適だと思います。だから私は辞書を使用してみてください
"id": {parent:ID, child:[id2, id3, id4....]}
約1000以上のカタログがあるので、すぐに混乱し、静的データに多くの間違いがあり、最終的な結果が使用可能になることがわかりました。また、今では数十個しか書いておらず、コードは混乱のように見えます。
このシンプルなカタログツリーを高性能で作成する方法をアドバイスしてください。ありがとう
クラスを作るだけです。
更新:
class TreeNode : IEnumerable<TreeNode>
{
private readonly Dictionary<string, TreeNode> _children =
new Dictionary<string, TreeNode>();
public readonly string ID;
public TreeNode Parent { get; private set; }
public TreeNode(string id)
{
this.ID = id;
}
public TreeNode GetChild(string id)
{
return this._children[id];
}
public void Add(TreeNode item)
{
if (item.Parent != null)
{
item.Parent._children.Remove(item.ID);
}
item.Parent = this;
this._children.Add(item.ID, item);
}
public IEnumerator<TreeNode> GetEnumerator()
{
return this._children.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public int Count
{
get { return this._children.Count; }
}
}
使用法は、静的に定義するのが非常に簡単です:
var tree = new TreeNode("Root")
{
new TreeNode("Category 1")
{
new TreeNode("Item 1"),
new TreeNode("Item 2"),
new TreeNode("Item 3"),
},
new TreeNode("Category 2")
{
new TreeNode("Item 1"),
new TreeNode("Item 2"),
new TreeNode("Item 3"),
new TreeNode("Item 4"),
}
};
編集
さらに簡単に作成するためのいくつかの機能...
public static TreeNode BuildTree(string tree)
{
var lines = tree.Split(new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries);
var result = new TreeNode("TreeRoot");
var list = new List<TreeNode> { result };
foreach (var line in lines)
{
var trimmedLine = line.Trim();
var indent = line.Length - trimmedLine.Length;
var child = new TreeNode(trimmedLine);
list[indent].Add(child);
if (indent + 1 < list.Count)
{
list[indent + 1] = child;
}
else
{
list.Add(child);
}
}
return result;
}
public static string BuildString(TreeNode tree)
{
var sb = new StringBuilder();
BuildString(sb, tree, 0);
return sb.ToString();
}
private static void BuildString(StringBuilder sb, TreeNode node, int depth)
{
sb.AppendLine(node.ID.PadLeft(node.ID.Length + depth));
foreach (var child in node)
{
BuildString(sb, child, depth + 1);
}
}
使用法:
var tree = TreeNode.BuildTree(@"
Cat1
Sub1
Item1
Item2
Item3
Sub2
Item1
Item2
Cat2
Sub1
Sub2
Item1
Item2
Sub3
Item1
Cat3
Cat4");
Node class を作成しました。これは参考になります。高速で、次のような追加のプロパティがあります。
あなたは単純なバイナリツリーを書くことができます、私は以下の擬似コードを書きます:
class TreeNode {
TreeNode Right;
TreeNode Left;
int id;
//...
}
class BinTree {
void Insert(TreeNode node)
{
while(true) {
if(node.id > target.id) {
if(target.Right != null) {
target = target.Right;
continue;
}
else {
target.Right = node;
break;
}
}
else if(node.id < target.id) {
if(target.Left != null) {
target = target.Left;
continue;
}
else {
target.Left = node;
break;
}
}
else {
throw new ArgumentException("Duplicated id");
}
}
}
TreeNode Search(int id)
{
TreeNode target = root;
while(target != null) {
if(id > target.id) {
target = target.Right;
}
else if(id < target.id) {
target = target.Left;
}
else {
return target;
}
}
return null;
}
}
ただし、データ数が非常に多い場合は、AVLツリーの方が効率的かもしれません