根据Sedgewick的算法书,他使用Java中的 Bag 集合来实现Graphs的邻接列表。因为在O(1)中搜索并允许从顶点到另一个顶点的重复边缘,所以它非常有意义。 可以使用列表但是它们在搜索中比在O(n)中慢,所以我会避免它。
不幸的是,.NET没有它。有像Wintellect这样的实现,但它们不是Portable(或.NET标准兼容)。 我该怎么用?
答案 0 :(得分:2)
经过一番思考后,我将自己的Bag实现为字典<'T,int> 这就像一个多重集或一个包。这是我在F#中的实现:
type Bag<'T when 'T : equality>() =
let dict = Dictionary<'T,int>()
let mutable count = 0
member x.Add = (x:>ICollection<'T>).Add
member x.Remove = (x:>ICollection<'T>).Remove
member x.Count = (x:>ICollection<'T>).Count
member x.Clear = (x:>ICollection<'T>).Clear
member x.ItemCount item =
match dict.TryGetValue item with
| true, itemCount -> itemCount
| _ -> 0
interface ICollection<'T> with
member x.Add item =
count <- count + 1
let itemCount =
match dict.TryGetValue item with
| true, itemCount -> itemCount
| _ -> 0
dict.[item] <- itemCount + 1
member x.Clear() = dict.Clear()
member x.Contains item = dict.ContainsKey item
member x.CopyTo(array, arrayIndex) =
x
|> Seq.take(array.Length - arrayIndex)
|> Seq.iteri (fun i item -> array.[i + arrayIndex] <- item)
member x.Count = count
member x.GetEnumerator() =
(x :> ICollection<'T>).GetEnumerator() :> Collections.IEnumerator
member x.GetEnumerator() =
let seq =
let innerSeq (kvp : KeyValuePair<'T,int>) =
Seq.init kvp.Value (fun _ -> kvp.Key)
dict |> Seq.map innerSeq |> Seq.collect id
seq.GetEnumerator()
member x.IsReadOnly = false
member x.Remove item =
match dict.TryGetValue item with
| true, 1 ->
count <- count - 1
dict.Remove item
| true, itemCount ->
count <- count - 1
dict.[item] <- itemCount - 1
true
| _ -> false