[Haskell-cafe] Re: Updating doubly linked lists
apfelmus at quantentunnel.de
Wed Jan 7 04:55:26 EST 2009
Dan Weston wrote:
> I hope the code is better than my description! :) The structure is more
> Nothing(RK 0 _)
> Nothing(RK 1 _)
> A(RK 2 4)
> B(RK 3 6)
> C(RK 2 0)
>> The root of the tree is the center and you can descend on the right.
>> But with this structure, walking from A to B is O(d) = O(n)
>> (where d is the distance from the origin,
>> n the side length of the grid) instead of O(1).
> No. The tree is [[Node]], where the outer list has one element for each
> radius that has an occupied node and each inner list has the number of
> nodes at the given radius.
> You descend the spine of the outer list radially in O(deltaR) time,
> which for incremental moves is O(1).
> Then you search for an existing inner list element in O(nk(r)), which
> stays fairly constant for reasonable paths (basically, the width of a
> path swath).
Ah, so you're using a sparse representation for grids. That's a good
idea! Unfortunately, it doesn't help when the grid is a full rectangle,
i.e. when nk(r) becomes proportional to r.
The (most likely unattainable) goal I had in mind is to create a zipper
for the full grid that supports O(1) operations.
>> I mean, O(d) may be fine for you, but it's not O(1) for everything as
>> advertised. :)
> d is not the distance from the origin, it is nk(r), the number of nodes
> at a given radius: d(2) = 2, d(3) = 1.
> An outward radial path will only expand the tree linearly, not
> quadratically, in size.
Well, that's still linear in the side length of a full grid. Directly using
Data.Map (Integer,Integer) a
would improve that to a logarithm. Of course, your structure can be
enhanced by using a Data.Map instead of a linked list for each ring à la
[Data.Map Integer a]
This will give O(log nk(r)) movements, but that's still not constant time.
More information about the Haskell-Cafe