を私は解決策は、彼らがO(N^2)について私たちを与えることが示唆されたと考え出してみました複雑。
私の場合(私はツリーに組み込まれる約50kのアイテムを持っています)、それは完全に容認できませんでした。
複雑さO(n * log(n))[n回getById、getByIdはO(log(n))を持つ次の解になりました(それぞれの項目に親が1つしかなく、 ))複雑]:
static List<Item> BuildTreeAndReturnRootNodes(List<Item> flatItems)
{
var byIdLookup = flatItems.ToLookup(i => i.Id);
foreach (var item in flatItems)
{
if (item.ParentId != null)
{
var parent = byIdLookup[item.ParentId.Value].First();
parent.Children.Add(item);
}
}
return flatItems.Where(i => i.ParentId == null).ToList();
}
完全なコードスニペット:
class Program
{
static void Main(string[] args)
{
var flatItems = new List<Item>()
{
new Item(1),
new Item(2),
new Item(3, 1),
new Item(4, 2),
new Item(5, 4),
new Item(6, 3),
new Item(7, 5),
new Item(8, 2),
new Item(9, 3),
new Item(10, 9),
};
var treeNodes = BuildTreeAndReturnRootNodes(flatItems);
foreach (var n in treeNodes)
{
Console.WriteLine(n.Id + " number of children: " + n.Children.Count);
}
}
// Here is the method
static List<Item> BuildTreeAndReturnRootNodes(List<Item> flatItems)
{
var byIdLookup = flatItems.ToLookup(i => i.Id);
foreach (var item in flatItems)
{
if (item.ParentId != null)
{
var parent = byIdLookup[item.ParentId.Value].First();
parent.Children.Add(item);
}
}
return flatItems.Where(i => i.ParentId == null).ToList();
}
class Item
{
public readonly int Id;
public readonly int? ParentId;
public Item(int id, int? parent = null)
{
Id = id;
ParentId = parent;
}
public readonly List<Item> Children = new List<Item>();
}
}
はフラットなリストは、どのような方法で注文していることですか?子どもの前に親が常に出現するように、そのような秩序を保証することができますか?あるいは、親の前に子どもを迎え入れるかもしれませんか? –
'Dictionary'を使ってidを 'Group'sにマップし、それを使ってアイテムを追加する親を検索します。これは、ツリーが再帰的なデータ構造であるという事実の他に、再帰を伴いません。 –
millimoose
'flatList'の型は何ですか? 'var'はそこに多くの情報を与えません。 – JLRishe