简体   繁体   中英

stl list - complexity

Are all the inserts (anywhere) for the list constant?

What about access?

Front, back - constant time?

and in the middle of the list - linear time?

Inserts anywhere in a std::list are constant time operations.

That said, before you can insert, you need to get an iterator to the location you'd like to insert to, which is a linear time operation unless you're talking about the front or back.

http://www.sgi.com/tech/stl/List.html

A list is a doubly linked list. That is, it is a Sequence that supports both forward and backward traversal, and (amortized) constant time insertion and removal of elements at the beginning or the end, or in the middle. Lists have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed

With regards to access, if you're going to search for an element somewhere in the middle, it'll take linear time. But once you've got an iterator, it'll be (of course) constant time access, and it won't be invalidated by other insertions or removals.

Note that, mainly due to better locality of data, in practice std::vector is often faster than std::list , even where in theory it should be the other way around. So the default sequential container should be std::vector .

If you doubt, first measure whether that container is critical at all (no use in increasing the speed of a piece of code even ten times, if that piece only uses 2% of the overall time), then compare measurements with std::list and std::deque and make your pick.

Insertion of a single element into the std::list<> takes constant time, regardless of where you insert it. Note, that std::list<> is not an inherently ordered container, meaning that it is you who specify where exactly to insert the new element. No wonder, the time is linear.

Inserting ("splicing") a [sub]sequence of elements moved from another list into this one (ie std::list<>::splice method) takes either constant time or linear time (linear in the number of element inserted). This happens because the implementation if std::list<> has a choice of either:

(1) implementing std::list<>::size method in constant time, and paying for it by implementing std::list<>::splice in linear time, or

(2) implementing std::list<>::splice method in constant time, and paying for it by implementing std::list<>::size in linear time.

You can have either this or that, but you can't have both. The decision to follow a specific approach is up to the implementation.

It is guaranteed by the C++ Standard 23.2.2/1:

A list is a kind of sequence that supports bidirectional iterators and allows constant time insert and erase operations anywhere within the sequence , with storage management handled automatically. Unlike vectors (23.2.4) and deques (23.2.1), fast random access to list elements is not supported, but many algorithms only need sequential access anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM