mirror of https://github.com/CGAL/cgal
370 lines
16 KiB
TeX
370 lines
16 KiB
TeX
%% ============================================================================
|
|
%% The CGAL Reference Manual
|
|
%% Chapter: STL Extensions - The Reference Part
|
|
%% ----------------------------------------------------------------------------
|
|
%% file : doc_tex/STL_Extension_ref/multiset.tex
|
|
%% author: Ron Wein
|
|
%% ----------------------------------------------------------------------------
|
|
%% $CGAL_Chapter: STL_Extension $
|
|
%% $Id$
|
|
%% $Date$
|
|
%% ============================================================================
|
|
|
|
%% +=========================================================================+
|
|
|
|
\begin{ccRefClass}{Multiset<Type,Compare,Allocator>}
|
|
\label{class:cgal_multimap}
|
|
\ccCreationVariable{s}
|
|
|
|
\ccDefinition
|
|
%============
|
|
|
|
An instance \ccVar\ of the parametrized data type \ccRefName\ is a
|
|
multi-set of elements of type \ccc{Type}, represented as a red-black tree
|
|
(see~\cite[Chapter~13]{clrs-ia-01} for an excellent introduction to red-black
|
|
trees).
|
|
The main difference between \ccRefName\ and \stl's \ccc{multiset} is that
|
|
the latter uses a less-than functor with a Boolean return type, while our
|
|
\ccRefName\ class is parameterized by a comparison functor \ccc{Compare} that
|
|
returns the three-valued \ccc{Comparison_result} (namely it returns either
|
|
\ccc{SMALLER}, \ccc{EQUAL}, or \ccc{LARGER}). It is thus possible to maintain
|
|
the underlying red-black tree with less invocations of the comparison functor.
|
|
This leads to a speedup of about 5\% even if we maintain a set of integers.
|
|
When each comparison of two elements of type \ccc{Type} is an expensive
|
|
operation (for example, when they are geometric entities represented using
|
|
exact arithmetic), the usage of a three-valued comparison functor can lead to
|
|
considerable decrease in the running times.
|
|
|
|
Moreover, \ccRefName\ allows the insertion of an element into the set given
|
|
its {\em exact} position, and not just using an insertion hint, as done by
|
|
\ccc{std::multiset}. This can further reduce the running times, as additional
|
|
comparison operations can be avoided.
|
|
|
|
In addition, the \ccRefName\ guarantees that the order of elements sent to the
|
|
comparison functor is fixed. For example, if we insert a new element \ccc{x}
|
|
into the set (or erase an element from the set), then we always invoke
|
|
\ccc{Compare() (x, y)} (and never \ccc{Compare() (y, x)}), where \ccc{y} is an
|
|
element already stored in the set. This behavior, not supported by
|
|
\ccc{std::multiset}, is sometimes crucial for designing more efficient
|
|
comparison predicates.
|
|
|
|
\ccRefName\ also allows for look-up of keys whose type may differ from
|
|
\ccc{Type}, as long as users supply a comparison functor \ccc{CompareKey},
|
|
where \ccc{CompareKey() (key, y)} returns the three-valued
|
|
\ccc{Comparison_result} (\ccc{key} is the look-up key and \ccc{y} is an
|
|
element of type \ccc{Type}). Indeed, it is very convenient to look-up
|
|
equivalent objects in the set given just by their key. We note however that
|
|
it is also possible to use a key of type \ccc{Type} and to employ the default
|
|
\ccc{Compare} functor for the look-up, as done when using the
|
|
\ccc{std::multiset} class.
|
|
|
|
\begin{ccAdvanced}
|
|
|
|
Finally, \ccRefName\ introduces the \ccc{catenate()} and \ccc{split()}
|
|
functions. The first function operates on \ccVar\ and accepts a second
|
|
set \ccVar', such that the maximum element in \ccVar\ is not greater than
|
|
the minimal element in \ccVar', and concatenates \ccVar' to \ccVar. The
|
|
second function splits \ccVar\ into two sets,one containing all the
|
|
elements that are less than a given key, and the other contains all
|
|
elements greater than (or equal to) this key.
|
|
|
|
\end{ccAdvanced}
|
|
|
|
\ccParameters
|
|
%------------
|
|
|
|
The \ccc{Multiset} class-template has three parameters:
|
|
\begin{itemize}
|
|
\item \ccc{Type} --- the type of the stored elements.
|
|
\item \ccc{Compare} --- the comparison-functor type. This type should provide
|
|
the following operator for comparing two \ccc{Type} elements, namely: \\
|
|
\ccc{Comparison_result operator() (const Type& t1, const Type& t2) const;}\\
|
|
The \ccc{CGAL::Compare<Type>} functor is used by default. In this case,
|
|
\ccc{Type} must support an equality operator (\ccc{operator==}) and a
|
|
less-than operator (\ccc{operator<}).
|
|
\item \ccc{Allocator} --- the allocator type. \\
|
|
\ccc{CGAL_ALLOCATOR} is used by default.
|
|
\end{itemize}
|
|
|
|
\ccInclude{CGAL/Multiset.h}
|
|
|
|
\ccHeading{Assertions}
|
|
%---------------------
|
|
|
|
The assertion and precondition flags for the \ccc{Multiset} class
|
|
use \ccc{MULTISET} in their names (i.e., \ccc{CGAL_MULTISET_NO_ASSERTIONS} and
|
|
\ccc{CGAL_MULTISET_NO_PRECONDITIONS}).
|
|
|
|
\ccTypes
|
|
%-------
|
|
|
|
In compliance with \stl, the types \ccc{value_type} and \ccc{key_type}
|
|
(both equivalent to \ccc{Type}), \ccc{reference} and \ccc{const_reference}
|
|
(reference to a value-type), \ccc{key_compare} and \ccc{value_compare}
|
|
(both equivalent to \ccc{Compare}), \ccc{size_type} and \ccc{difference_type}
|
|
are defined as well.
|
|
|
|
\ccNestedType{iterator}{}
|
|
\ccGlue
|
|
\ccNestedType{const_iterator}
|
|
{bi-directional iterators for the elements stored in the set.}
|
|
|
|
\ccNestedType{reverse_iterator}{}
|
|
\ccGlue
|
|
\ccNestedType{const_reverse_iterator}
|
|
{reverse bi-directional iterators for the elements stored in the set.}
|
|
|
|
\ccCreation
|
|
%----------
|
|
|
|
\ccConstructor{Multiset<Type,Compare,Allocator>();}{
|
|
creates an an empty set \ccVar\ that uses a default comparison
|
|
functor.}
|
|
|
|
\ccConstructor{Multiset<Type,Compare,Allocator>(
|
|
const Compare& comp);}{
|
|
creates an an empty set \ccVar\ that uses the given comparison
|
|
functor \ccc{comp}.}
|
|
|
|
\ccConstructor{template <class InputIterator>
|
|
Multiset<Type,Compare,Allocator>(
|
|
InputIterator first, InputIterator last,
|
|
const Compare& comp = Compare());}{
|
|
creates a set \ccVar\ containing all elements in the range
|
|
\ccc{[first, last)}, that uses the comparison
|
|
functor \ccc{comp}.}
|
|
|
|
\ccConstructor{Multiset<Type,Compare,Allocator>(
|
|
const Multiset<Type,Compare,Allocator>& other);}{
|
|
copy constructor.}
|
|
|
|
\ccMethod{const Multiset<Type,Compare,Allocator>& operator= (
|
|
const Multiset<Type,Compare,Allocator>& other);}{
|
|
assignment operator.}
|
|
|
|
\ccMethod{void swap (Multiset<Type,Compare,Allocator>& other);}{
|
|
swaps the contents of \ccVar\ with those of the other set.}
|
|
|
|
\ccHeading{Access Member Functions}
|
|
%----------------------------------
|
|
|
|
\ccMethod{Compare key_comp() const;}{
|
|
the comparison functor used.}
|
|
\ccGlue
|
|
\ccMethod{Compare value_comp() const;}{
|
|
the comparison functor used (same as above).
|
|
Both functions have a non-const version that return a reference
|
|
to the comparison functor.}
|
|
|
|
\ccMethod{bool empty ();}{
|
|
returns \ccc{true} if the set is empty, \ccc{false} otherwise.}
|
|
|
|
\ccMethod{size_t size ();}{
|
|
returns the number of elements stored in the set.}
|
|
|
|
\ccMethod{size_t max_size ();}{
|
|
returns the maximal number of elements the set can store
|
|
(same as \ccc{size()}).}
|
|
|
|
\ccMethod{iterator begin();}{
|
|
returns an iterator pointing to the first element stored in the set
|
|
(a \ccc{const} version is also available).}
|
|
|
|
\ccMethod{iterator end();}{
|
|
returns an iterator pointing beyond the last element stored in the set
|
|
(a \ccc{const} version is also available).}
|
|
|
|
\ccMethod{reverse_iterator rbegin();}{
|
|
returns a reverse iterator pointing beyond the last element stored in the
|
|
set (a \ccc{const} version is also available).}
|
|
|
|
\ccMethod{reverse_iterator rend();}{
|
|
returns a reverse iterator pointing to the first element stored in the set
|
|
(a \ccc{const} version is also available).}
|
|
|
|
\ccHeading{Comparison Operations}
|
|
%--------------------------------
|
|
|
|
\ccMethod{bool operator== (
|
|
const Multiset<Type,Compare,Allocator>& other) const;}{
|
|
returns \ccc{true} if the sequences of elements in the two sets are
|
|
pairwise equal (using the comparison functor).}
|
|
|
|
\ccMethod{bool operator< (
|
|
const Multiset<Type,Compare,Allocator>& other) const;}{
|
|
returns \ccc{true} if the element sequence in \ccVar{} is
|
|
lexicographically smaller than the element sequence of \ccc{other}.}
|
|
|
|
\ccHeading{Insertion Methods}
|
|
%----------------------------
|
|
|
|
\ccMethod{iterator insert (const Type& x);}{
|
|
inserts the element \ccc{x} into the set and returns an iterator pointing
|
|
to the newly inserted element.}
|
|
|
|
\ccMethod{template <class InputIterator>
|
|
void insert (InputIterator first, InputIterator last);}{
|
|
inserts all elements in the range \ccc{[first, last)} into
|
|
the set.}
|
|
|
|
\ccMethod{iterator insert (iterator position, const Type& x);}{
|
|
inserts the element \ccc{x} with a given iterator used as a hint for the
|
|
position of the new element. It Returns an iterator pointing to the
|
|
newly inserted element.}
|
|
|
|
\ccMethod{iterator insert_before (iterator position, const Type& x);}{
|
|
inserts the element \ccc{x} as the predecessor of the element at the given
|
|
position.
|
|
\ccPrecond\ The operation does not violate the set order --- that is,
|
|
\ccc{x} is not greater than the element pointed by
|
|
\ccc{position} and not less than its current predecessor.}
|
|
|
|
\ccMethod{iterator insert_after (iterator position, const Type& x);}{
|
|
inserts the element \ccc{x} as the successor of the element at the given
|
|
position.
|
|
\ccPrecond\ The operation does not violate the set order --- that is,
|
|
\ccc{x} is not less than the element pointed by
|
|
\ccc{position} and not greater than its current successor.}
|
|
|
|
\ccHeading{Removal Methods}
|
|
%--------------------------
|
|
|
|
\ccMethod{size_t erase (const Type& x);}{
|
|
erases all elements equivalent to \ccc{x} from the set and returns the
|
|
number of erased elements.}
|
|
|
|
\ccMethod{void erase (iterator position);}{
|
|
erases the element pointed by \ccc{position}.}
|
|
|
|
\ccMethod{void clear ();}{
|
|
clears the set (erases all stored elements).}
|
|
|
|
\ccHeading{Look-up Methods}
|
|
%--------------------------
|
|
|
|
All methods listed in this section can also accept a \ccc{Type} element
|
|
as a look-up key. In this case, it is not necessary to supply a \ccc{CompareKey}
|
|
functor, as the \ccc{Compare} functor will be used by default.
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
iterator find (const Key& key, const CompareKey& comp_key);}{
|
|
searches for the an element equivalent to \ccc{key} in the set. If the
|
|
set contains objects equivalent to \ccc{key}, it returns an iterator
|
|
pointing to the first one. Otherwise, \ccc{end()} is returned (a
|
|
\ccc{const} version is also available).}
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
size_t count (const Key& key, const CompareKey& comp_key) const;}{
|
|
returns the number of elements equivalent to \ccc{key} in the set.}
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
iterator lower_bound (const Key& key, const CompareKey& comp_key);}{
|
|
returns an iterator pointing to the first element in the set that is not
|
|
less than \ccc{key}. If all set elements are less than \ccc{key},
|
|
\ccc{end()} is returned (a \ccc{const} version is also available).}
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
iterator upper_bound (const Key& key, const CompareKey& comp_key);}{
|
|
returns an iterator pointing to the first element in the set that is
|
|
greater than \ccc{key}. If no set element is greater than \ccc{key},
|
|
\ccc{end()} is returned (a \ccc{const} version is also available).}
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
std::pair<iterator,iterator>
|
|
equal_range (const Key& key, const CompareKey& comp_key);}{
|
|
returns the range of set elements equivalent to the given key, namely
|
|
\ccc{(lower_bound(key), upper_bound(key))} (a \ccc{const} version is
|
|
also available).}
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
std::pair<iterator,bool>
|
|
find_lower (const Key& key, const CompareKey& comp_key);}{
|
|
returns a pair comprised of \ccc{lower_bound(key)} and a Boolean flag
|
|
indicating whether this iterator points to an element equivalent to
|
|
the given key (a \ccc{const} version is also available).}
|
|
|
|
\begin{ccAdvanced}
|
|
|
|
\ccHeading{Special Operations}
|
|
%-----------------------------
|
|
|
|
\ccMethod{void replace (iterator position, const Type& x);}{
|
|
replaces the element stored at the given position with \ccc{x}.
|
|
\ccPrecond\ The operation does not violate the set order --- that is,
|
|
\ccc{x} is not less that \ccc{position}'s predecessor and
|
|
not greater than its successor.}
|
|
|
|
\ccMethod{void swap (iterator pos1, iterator pos2);}{
|
|
swaps places between the two elements given by \ccc{pos1} and \ccc{pos2}.
|
|
\ccPrecond\ The operation does not violate the set order --- that is,
|
|
\ccc{pos1} and \ccc{pos2} store equivalent elements.}
|
|
|
|
\def\ccLongParamLayout{\ccTrue}
|
|
\ccMethod{void catenate (Self& s_prime);}{
|
|
concatenates all elements in \ccc{s_prime} into \ccVar\ and clears
|
|
\ccc{s_prime}.
|
|
All iterators to \ccVar\ and to \ccc{s_prime} remain valid.
|
|
\ccPrecond\ The maximal element in \ccVar\ is not greater than the minimal
|
|
element in \ccc{s_prime}.}
|
|
|
|
\ccMethod{template <class Key, class CompareKey>
|
|
void split (Key key, CompareKey comp_key, Self& s_prime);}{
|
|
splits \ccVar\, such that it contains all elements that are less than
|
|
the given \ccc{key} and such that \ccc{s_prime} contains all other elements.
|
|
\ccPrecond\ \ccc{s_prime} is initially empty.}
|
|
|
|
\ccMethod{void split (iterator position, Self& s_prime);}{
|
|
splits \ccVar\, such that it contains all set elements in the range
|
|
\ccc{[begin, position)} and such that \ccc{s_prime} contains all elements
|
|
in the range \ccc{[position, end())}.
|
|
\ccPrecond\ \ccc{s_prime} is initially empty.}
|
|
\def\ccLongParamLayout{\ccTrue}
|
|
|
|
\end{ccAdvanced}
|
|
|
|
\ccImplementation
|
|
%================
|
|
|
|
\ccc{Multiset} uses a proprietary implementation of a red-black tree
|
|
data-structure. The red-black tree invariants guarantee that the height of a
|
|
tree containing $n$ elements is $O(\log{n})$ (more precisely, it is bounded by
|
|
$2 \log_{2}{n}$). As a consequence, all methods that accept an element and need
|
|
to locate it in the tree (namely \ccc{insert(x)}, \ccc{erase(x)},
|
|
\ccc{find(x)}, \ccc{count(x)}, \ccc{lower_bound(x)} , \ccc{upper_bound(x)},
|
|
\ccc{find_lower(x)} and \ccc{equal_range(x)}) take $O(\log{n})$ time and
|
|
perform $O(\log{n})$ comparison operations.
|
|
|
|
On the other hand, the set operations that accept a position iterator (namely
|
|
\ccc{insert_before(pos, x)}, \ccc{insert_after(pos, x)} and \ccc{erase(pos)})
|
|
are much more efficient as they can be performed at a {\em constant} amortized
|
|
cost (see~\cite{gs-dfbt-78} and~\cite{t-dsna-83} for more details).
|
|
More important, these set operations require {\em no} comparison operations.
|
|
Therefore, it is highly recommended to maintain the set via iterators
|
|
to the stored elements, whenever possible. The function \ccc{insert(pos, x)}
|
|
is safer to use, but it takes amortized $O(\min\{d,\log{n}\})$ time, where $d$
|
|
is the distance between the given position and the true position of \ccc{x}.
|
|
In addition, it always performs at least two comparison operations.
|
|
|
|
\begin{ccAdvanced}
|
|
|
|
The \ccc{catenate()} and \ccc{split()} functions are also very efficient, and
|
|
can be performed in $O(\log{n})$ time, where $n$ is the total number of
|
|
elements in the sets, and without performing any comparison operations
|
|
(see~\cite{t-dsna-83} for the details).
|
|
Note however that the size of two sets resulting from a split operation is
|
|
initially unknown, as it is impossible to compute it in less than linear time.
|
|
Thus, the first invocation of \ccc{size()} on such a set takes linear time,
|
|
and {\em not} constant time.
|
|
|
|
\end{ccAdvanced}
|
|
|
|
The design is derived from the \stl\ \ccc{multiset} class-template (see,
|
|
e.g,~\cite{cgal:ms-strg-96}), where the main differences between the two
|
|
classes are highlighted in the class definition above.
|
|
|
|
\end{ccRefClass}
|
|
|
|
|
|
|
|
|