mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-31 03:47:16 +02:00
Filled in the comparison between associative containers and unordered
containers. Now needs to be paired back down. [SVN r3044]
This commit is contained in:
@ -1,27 +1,164 @@
|
||||
[section:comparison Comparison with Associative Containers]
|
||||
|
||||
* The elements in an unordered container are organised into buckets, in an
|
||||
unpredictable order. There are member functions to access these buckets which
|
||||
was described earlier.
|
||||
* The unordered associative containers don't support any comparison operators.
|
||||
* Instead of being parameterized by an ordering relation `Compare`,
|
||||
the unordered associative container are parameterized by a function object
|
||||
`Hash` and an equivalence realtion `Pred`. The member types and accessor
|
||||
member functions reflect this.
|
||||
* Because of this, equivalent keys for unordered container are defined in
|
||||
terms of `Pred`, while for the associative containers it's defined in terms
|
||||
of `Compare`.
|
||||
* Unordered associative containers' iterators can be invalidated by rehashing
|
||||
or by inserting elements.
|
||||
* Unordered associative containers' iterators are of at least the forward
|
||||
iterator category. Associative containers' iterators are bidirectional.
|
||||
* The unordered associative containers' constructors have extra parameters
|
||||
for the number of buckets, the hash function and the equality predicate.
|
||||
* The unordered associative container don't have a `lower_bound` or
|
||||
`upper_bound` method - they wouldn't make any sense since the elements
|
||||
aren't ordered.
|
||||
* TODO: Complexity guarantees.
|
||||
* TODO: Behaviour when exceptions throw. The unordered containers seem
|
||||
a lot stronger defined here?
|
||||
TODO: This page probably contains too much information. Some of the comparisons
|
||||
can probably be paired down (especially the complexity stuff) and some of the
|
||||
extra details belong elsewhere.
|
||||
|
||||
TODO: I've omitted some similarities - perhaps I should include them.
|
||||
|
||||
[table Interface differences.
|
||||
[[Associative Containers] [Unordered Associative Containers]]
|
||||
|
||||
[
|
||||
[Parameterized by an ordering relation `Compare`]
|
||||
[Parameterized by a function object `Hash` and an equivalence relation
|
||||
`Pred`]
|
||||
]
|
||||
[
|
||||
[`Compare` exposed by member typedef `key_compare`, accessed by member function `key_comp()`]
|
||||
[`Hash` exposed by member typedef `hasher`, accessed by member function `hash_function()`.\n`Pred` by member typedef `key_equal` and member function `key_eq()`.]
|
||||
]
|
||||
[
|
||||
[Member typedef `value_compare` supplies an ordering comparison for member elements, accessed by member function `value_comp()`.]
|
||||
[No equivalent. No idea why.]
|
||||
]
|
||||
[/TODO: Mention a range? This is meant to be differences but this doesn't
|
||||
seem to be complete.]
|
||||
[
|
||||
[Constructors have optional extra parameters for the comparison object.]
|
||||
[Constructors have optional extra parameters for the initial minimum
|
||||
number of buckets, a hash function and an equality object.]
|
||||
]
|
||||
|
||||
[
|
||||
[Keys `k1`, `k2` are considered equivalent if
|
||||
`!Compare(k1, k2) && !Compare(k2, k1)`]
|
||||
[Keys `k1`, `k2` are considered equivalent if `Pred(k1, k2)`]
|
||||
]
|
||||
[
|
||||
[Member function `lower_bound(k)` and `upper_bound(k)`]
|
||||
[No equivalent. Since the elements aren't ordered `lower_bound` and
|
||||
`upper_bound` would be meaningless.]
|
||||
]
|
||||
[
|
||||
[`equal_range(k)` returns an empty range at the position that k
|
||||
would be inserted if k isn't present in the container.]
|
||||
[`equal_range(k)` returns a range at the end of the container if
|
||||
k isn't present in the container. It can't return a positioned
|
||||
range as k could be inserted into multiple place. To find out the
|
||||
bucket that k would be inserted into use `bucket(k)`. But remember
|
||||
that an insert can cause the container to rehash - meaning that the
|
||||
element can be inserted into a different bucket.]
|
||||
]
|
||||
[
|
||||
[`iterator`, `const_iterator` are of the biderctional category.]
|
||||
[`iterator`, `const_iterator` are of at least the forward category.]
|
||||
]
|
||||
[
|
||||
[Inserts do not invalidate iterators or references to the container.]
|
||||
[Inserts can invalidate iterators but not references to the container.]
|
||||
]
|
||||
[
|
||||
[Iterators iterate through the container in the order defined by
|
||||
the comparison object.]
|
||||
[Iterators iterate through the container in an arbitrary order, that
|
||||
can change as elements are inserted. Although, equivalent elements
|
||||
are always adjacent.]
|
||||
]
|
||||
[
|
||||
[No equivalent]
|
||||
[Local iterators can be used to iterate through individual buckets.
|
||||
(I don't think that the order of local iterators and iterators are
|
||||
required to have any correspondence.)]
|
||||
]
|
||||
[
|
||||
[Can be compared using the `==`, `!=`, `<`, `<=`, `>`, `>=` operators]
|
||||
[No comparison operators are defined]
|
||||
]
|
||||
[
|
||||
[]
|
||||
[When inserting with a hint, implementations are permitted to ignore
|
||||
the hint.]
|
||||
]
|
||||
[
|
||||
[`erase` never throws an exception]
|
||||
[The containers hash or predicate function can throw exceptions
|
||||
from `erase`]
|
||||
]
|
||||
]
|
||||
|
||||
[table Complexity Guarantess
|
||||
[[Operation] [Associative Containers] [Unordered Associative Containers]]
|
||||
[
|
||||
[Construction of empty container]
|
||||
[constant]
|
||||
[/TODO: Do I meet this?]
|
||||
[O(/n/) where /n/ is the minimum number of buckets.]
|
||||
]
|
||||
[
|
||||
[Construction of container from a range of /N/ elements]
|
||||
[O(/N/ log /N/), O(/N/) if the range is sorted with `value_comp()`]
|
||||
[Average case O(/N/), worst case
|
||||
O(/N/'''<superscript>2</superscript>''')]
|
||||
]
|
||||
[
|
||||
[Insert a single element]
|
||||
[logarithmic]
|
||||
[Average case constant, worst case linear]
|
||||
]
|
||||
[
|
||||
[Insert a single element with a hint]
|
||||
[Amortized constant if t elements inserted right after hint,
|
||||
logarithmic otherwise]
|
||||
[Average case constant, worst case linear (ie. the same as
|
||||
a normal insert).]
|
||||
]
|
||||
[
|
||||
[Inserting a range of /N/ elements]
|
||||
[/N/ log(`size()`+/N/)]
|
||||
[Average case O(/N/), worst case O(/N/ * 'size()')]
|
||||
]
|
||||
[
|
||||
[Erase by key, `k`]
|
||||
[O(log(`size()`) + `count(k)`)]
|
||||
[Average case: O(`count(k)`), Worst case: O(`size()`)]
|
||||
]
|
||||
[
|
||||
[Erase a single element by iterator]
|
||||
[Amortized constant]
|
||||
[Average case: O(1), Worst case: O(`size()`)]
|
||||
]
|
||||
[
|
||||
[Erase a range of /N/ elements]
|
||||
[O(log(`size()`) + /N/)]
|
||||
[Average case: O(/N/), Worst case: O(`size()`)]
|
||||
]
|
||||
[
|
||||
[Clearing the container]
|
||||
[O(`size()`)]
|
||||
[O(`size()`)]
|
||||
]
|
||||
[
|
||||
[Find]
|
||||
[logarithmic]
|
||||
[Average case: O(/N/), Worst case: O(`size()`)]
|
||||
]
|
||||
[/ TODO: Average case is probably wrong. ]
|
||||
[
|
||||
[Count]
|
||||
[O(log(`size()`) + `count(k)`)]
|
||||
[Average case: O(1), Worst case: O(`size()`)]
|
||||
]
|
||||
[
|
||||
[`equal_range(k)`]
|
||||
[logarithmic]
|
||||
[Average case: O(`count(k)`), Worst case: O(`size()`)]
|
||||
]
|
||||
[
|
||||
[`lower_bound`,`upper_bound`]
|
||||
[logarithmic]
|
||||
[n/a]
|
||||
]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
Reference in New Issue
Block a user