Boost logo

Boost :

From: Rene Rivera (grafikrobot_at_[hidden])
Date: 2006-10-31 10:00:58


Martin Knoblauch Revuelta wrote:
> On 10/31/06, Rene Rivera <grafikrobot_at_[hidden]> wrote:

>> * There's no need for the m_next and m_prev fields. You can do inorder,
>> preorder, postorder, and others without them.
>
> Yes, I could, but operators ++ and -- would become O(log n).

I beg to differ. All those traversals can be implemented O(1) per
iteration. This is the case for all binary trees.

> Many
> operations benefit from the posibility of fast iteration through
> m_next and m_prev. For example: begin() and end() are O(1).

If you want constant time for begin() and end() you could store
references to them in the container and update them as needed over time.

>> * I suspect you don't need the m_height either. But I don't know what
>> you are using it for yet.
>
> For balance. IMO, the logic of re-balancing becomes simpler by having
> m_height instead of the usual {-1,0,+1}.

Right, AVL balancing... In my version I implemented a balancing that
uses the count/width directly obviating the need for extra coloring
information.

>> * In my rank tree implementation the only extra field per node is the
>> count, what you call width (as separate node and total). If I remember
>> correctly in CLRS they describe the possibility of the count not
>> directly reflecting the subtree+1 size to allow for sparse trees. I
>> suspect that you can remove the need for the different m_node_width and
>> m_total_width, using one only, by deducing the m_node_width from "count
>> - left_count - right_count".
>
> The width is based on the same concept as count, but they are not
> related at all. Note that W might be float, for example.

I don't see how making it a float invalidates the calculation as it's
the rank statistic invariant. Are you not using that invariant? If not,
what is your invariant?

> I might deduce m_total_width from m_node_width by recursing through
> the whole subtree every time. Obviously, this would spoil the whole
> thing.

Hm, I guess you aren't using the rank invariant then.

>> * I don't see how not having a static allocator prevents moving nodes
>> across equally typed containers.
>
> It shouldn't, but it depends on how correct is the allocator class. I
> read in the documentation of SGI that allocators must be fully static,
> allowing deallocation of something by a different object of that one
> used for allocation (perhaps even destructed in the meantime). Is this
> true for _all_ std and boost allocators too?

The pertinent passage is 20.1.5p4:

Implementations of containers described in this International Standard
are permitted to assume that their Allocator template parameter meets
the following two additional requirements beyond those in Table 32.

        — All instances of a given allocator type are required to be
interchangeable and always compare equal to each other.

>> * You should use the allocator types instead of making types out of the
>> value type directly.
>
> I don't understand. Do you mean the rebind trick? I thought this was
> the standard way.

I meant that instead of:

     typedef T & reference;
     typedef const T & const_reference;

You use:

     typedef typename A::reference reference;
     typedef typename A::const_reference const_reference;

>> * You have a variety of C style casts, and you happen to be casting
>> "this". That's frowned upon, and truthfully I can't see why you do it.
>
> I'll change them to C++ casts.

Hopefully you mean static_cast<>.

-- 
-- Grafik - Don't Assume Anything
-- Redshift Software, Inc. - http://redshift-software.com
-- rrivera/acm.org - grafik/redshift-software.com
-- 102708583/icq - grafikrobot/aim - grafikrobot/yahoo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk