Przechodzenie pomiędzy elementami listy stl

0

W jaki sposób mogę przejść po liście stlowej mając adres początkowego elementu i końcowego(adres początku nie musi być pierwszy może to być adres elementu 3 listy). Chodzi mi o możliwość przejścia tylko po pewnej części listy.

0

Temat na dziś - iteratory (w skrócie: abstrakcja w stylu wskaźników).

1

Aby zacząć iterować od wybranego miejsca potrzebujesz iteratora który na nie wskazuje, sam wskaźnik nie wystarczy. Więc w miejscu gdzie wyznaczasz start/koniec zakresu musisz posługiwać się iteratorami, nie wskaźnikami.

Kontener list (również set, multiset, map i multimap) ma taką właściwość, że każdy pojedynczy elementy od momentu wstawienia do momentu usunięcie z listy posiada stały iterator. Tzn. jeśli zapiszesz sobie iterator wskazujący na pewien element iterator ten będzie prawidłowy dopóki element nie zostanie usunięty z listy, inne elementy mogą być wstawiane/usuwane a iterator i tak pozostanie OK. Choć przeważnie zasada ta będzie dotyczyć również wskaźników na elementy (iteratory są opakowaniem na wskaźniki), to nie jest to niczym gwarantowane i nie wolno na tym polegać.

0

Bardzo bym prosiła o jakiś prosty przykład ilustrujący jak mogę to zrobić. Ogólnie jak przejść iteratorem przez całą listę wiem jak zrobić(używając begin() i end()), ale nigdzie nie mogłam znaleźć jak używając iteratora przejść po pewnej częsci.
Np dla poniższego kodu:

struct wierzcholek
{
unsigned int numer;
zbior *z;
wierzcholek(unsigned int nr)
{
numer=nr;
z=NULL;
}
};

void funkcja()
{
list<wierzcholek> wierzcholki;
int liczbaw=6;
for(int i=1;i<=liczbaw;i++)
{
wierzcholek *p=new wierzcholek(i);
wierzcholki.push_back(*p);
}
// i teraz jak dostać się np do elementu 3 w list<wierzcholki>, nie przegladając wszystkiego od początku

}

0

Używając kontenerów stl nie przechowuj wskaźników, tylko właśnie iteratory. Dodatkowo musisz sobie wcześniej ten wskaźnik do tego 3 elementu gdzieś zapisać, ponieważ lista nie jest kontenerem który by umożliwiał taki dostęp. Ogólnie bardzo rzadko lista jest lepszym rozwiązaniem niż vector, czy deque, nawet w przypadkach w których wydaje się na początku inaczej.

0
for(auto i = cont.begin() + 5; i != cont.begin() + 10; ++i) { ... }

Przejdzie Ci od 5 do 10 elementu.
Jednak w przypadku list trzeba zrobić:

auto start = cont.begin();
auto end = cont.begin();
std::advance(start, 5);
std::advance(end, 10);
for(auto i = start; i != end; ++i) { ... }
0

Okej dziękuję, jednak chodzi mi raczej o coś takiego że wstawiam elementy na listę, i zapamiętuję stały iterator do każdego elementu np: w wektorze. Potem przestawiając elementy w liście, żebym miała dostęp do każdego elementu i nie musiała się martwić o adres elementów. Potrzebuję coś takiego ponieważ muszę zrealizować graf w którym mam listę wierzchołków, i chciałabym mieć adres każdego wierzchołka na wyciągnięcie ręki, czyli np: w vector[1]- adres wierzcholka nr 1, vector[2]-adres wierzcholka nr 2 itp. i żeby te adresy ciągle wskazywały na te wierzchołki mimo przestawiania je między sobą w liście. Nie potrafię się jeszcze biegle posługiwać iteratorami, dlatego mam problem w zaimplementowaniu czegoś takiego.
I wtedy po prostu przeglądam wektor od pewnego momentu i mając dostęp do adresów wprowadzam potrzebne modyfikacje w wierzchołkach.

0

Jakie znaczenie ma kolejność wierzchołków na liście? Dlaczego w ogóle czujesz potrzebę iterowania do/do pewnego elementu?
Być może użycie innego kontenera załatwi sprawę. Musisz w każdym razie opisać problem bliżej. Pokaż też jakiś kod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1