accediendo a std :: list en el medio

I have a dummy question. I always read that C++ std::list container has constant time for inserting elements at the beginning, at the end and in the middle: Which is the correct way to insert an element directly in the middle of a std::list? Is maybe this one?

  std::list<int> l;
  l.push_back(10);
  l.push_back(20);
  l.push_back(30);
  l.push_back(40);
  l.push_back(50);
  l.push_back(60);
  l.insert( l.end()- l.begin() /2 ); //? is this 
  // inserting directly in the middle?

When we say 'inserting in the middle' do we really mean that we save linear time to go from the beginning of the list to the desired point ( traversing one by one through all linked elements in between)?

preguntado el 08 de noviembre de 11 a las 14:11

They don't mean the exact middle -- just somewhere other than the beginning or end. -

Hi Vaughn!Thanks for the clarification...the more I do this job and the more I think that it is really time to start reading some good old-style adventure book..to relax a bit and reading things without too much checking about the strict meaning. Cheers AFG -

5 Respuestas

You can do the iterator maths generically like this:

 std::list<int>::iterator it = l.begin();
 std::advance(it, std::distance(l.begin(), l.end())/2);
 l.insert(it, value);

This will work for any iterator type (except OutputIterator or InputIterator)

Por supuesto que es mucho más eficiente decir

 std::advance(it, l.size()/2);
 l.insert(it, value);

Desafortunadamente, l.insert(l.begin + (l.size()/2), value) won't work because list iterators aren't random access, therefore don't have operator+ defined (to prevent performance surprises!). Keep in mind that std::advance() podría ser un costoso operation depending on iterator type (it will be slow for iteradores inversos implemented on a forward-only container, e.g.).

respondido 08 nov., 11:19

En realidad, el .size() version isn't mucho más eficiente para std::list. It's about equal, you just save some tokens typing it. - jpalecek

@jpalecek: In C++11, it is way more efficient, constant time vs. linear. In C++03, it was implementation dependent whether size() was constant or linear, but distance() pretty much has to be linear. - Mike Seymour

@MikeSeymour: Ah, thanks for the explanation! It seems it was the same in C++03, but different in the original SGI STL (which OTOH required that splice is constant time). - jpalecek

Here, "the middle" means an arbitrary point in the list, as long as you already have an iterator referring to that point. Given that, insertion is just a matter of modifying a few pointers around the insertion point.

If you don't already have an iterator for the insertion point, and it isn't somewhere simple like the beginning or the end, then it will take linear time to walk through the list to find it.

respondido 08 nov., 11:19

When we say 'inserting in the middle' do we really mean that we save linear time to go from the beginning of the list to the desired point ( traversing one by one through all linked elements in between)?

Sí.
Basically, It means the list needs to just change pointers to insert a new element and not navigate the entire list or copy the contents etc.Hence the insertion is constant time, because there is no need of traversing the list or copying the containers etc.

respondido 08 nov., 11:18

Hmm... Correct explanation, but isn't that more like "no", rather than "yes"? - Michael Krelin - hacker

@MichaelKrelin-hacker: OP states "do we really mean that we save linear time to go from..". We do.Because there is no navigation only pointer rearrangement. - Alok Save

I see your point. I disagree, though, because OP means inserting in the very middle, which takes a bit of snooping around before we can actually find this point. - Michael Krelin - hacker

Inserting in the "middle" of a list means inserting somewhere other than the beginning or end. But doing an insertion requires an iterator to the insertion point. Once you have such an iterator, the insertion time is constant, but getting such an iterator in the first place is a separate issue.

respondido 08 nov., 11:19

No, when we say "inserting in the middle" we do not mean "finding the insertion point according to whatever criteria that takes traversing of the whole or indefinite part of the list".

respondido 08 nov., 11:19

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.