Say we are traversing a graph and want to quickly determine if a node has been seen before or not. We have a few set preconditions.
- Nodes have been marked with integers values 1..N
- Graph is implemented with nodes having an adjacency list
- Every integer value from 1..N occurs in the graph, which is of size N
Any ideas for doing this in a purely functional way?(No Hash tables or arrays allowed).
I want a data structure with two functions working on it; add(adds an encountered integer) and lookup(checks if integer has been added). Both should preferably take O(n) time amortized for N repetitions.
Is this possible?
-
You can use a Data.Set. You add an element by creating a new set from the old one with
insertand pass the new set around. You look up whether an element is a member of the set withmember. Both operations are O(log n).Perhaps, you could consider using a state monad to thread the passing of the set.
Chris Conway : I assume Data.Set will give logarithmic- or quasi-constant-time performance on addToSet and member, as opposed to expected constant-time performance with hash tables?namin : Chris, you're right. Data.Set insert and lookup operations are O(log n).mattiast : If your integers are small enough for the Int type, you can use Data.IntSet, which is optimized version of Set. -
Efficient element lookup in functional languages is quite hard.
Data.Set(as shown above) is implemented using a binary tree which can be built up in a purely functional way providing lookup operations in O(log n). HashTables (which aren't purely functional) would have O(1). -
I believe that Data.BitSet might be O(n).
0 comments:
Post a Comment