Strona 1 z 1

[C++] Lista jednokierunkowa

: 30 wrz 2015, o 16:24
autor: Igor V
Chcę napisać prostą, niecykliczną listę jednokierunkową z funkcją dodawania na końcu listy i wyświetlania wszystkich jej elementów po kolei.

Kod: Zaznacz cały

#include <iostream>

using namespace std;

class Element
{
    public:
    int id;
    string wyraz;
    Element *next;
    Element()
    {
        next=NULL;
    }
};

class Lista
{
    public:
    void dodaj(int _id, string _wyraz)
    {
       Element *nowy=new Element;

       nowy->id =_id;
       nowy->wyraz =_wyraz;

       if(pierwszy==NULL)
       {
           pierwszy=nowy;
       }
       else
       {
           while(pierwszy->next!=NULL)
           {
               pierwszy=pierwszy->next;
           }
           pierwszy->next=nowy;
       }
    }
    void wyswietl()
    {
       while(pierwszy->next!=NULL)
       {
           cout<<pierwszy->id;
           cout<<pierwszy->wyraz<<endl;
           pierwszy=pierwszy->next;
       }
    };
    Element *pierwszy;
    Lista()
    {
        pierwszy=NULL;
    }
};

int main()
{
    Lista *baza=new Lista;
    baza->dodaj(1,"A");
    baza->dodaj(2,"B");
    baza->dodaj(3,"C");
    baza->dodaj(4,"D");
    baza->wyswietl();

    return 0;
}
Po uruchomieniu program wypisuje tylko jeden element (np: 1A albo 4D).Zauważyłem że zawsze przedostatni.Więc to chyba błąd w funkcji wyswietl() ,ale nie potrafię go zlokalizować.

[C++] Lista jednokierunkowa

: 30 wrz 2015, o 16:49
autor: Dakurels
Problem jest taki, że przesuwasz często początek, przez co tracisz dostęp do niektórych elementów listy (linie 37 albo 46). Poza tym, while z linii 42 po dojściu do ostatniego elementu (którego następnik jest nullem) nic nie wypisze. Program ma jeszcze problemy takie jak (znów) w 42 linii odwołujesz się do nexta wskaźnika "pierwszy", który może być nullem i wysypać ci program.

Pozdrawiam

[C++] Lista jednokierunkowa

: 30 wrz 2015, o 18:17
autor: Igor V
Szczerze to nie bardzo widzę.Jeśli chodzi o 37 i 46 linijkę to chodziło mi o to że jak mam jakiś element listy (i wskaźnik "pierwszy" na niego) w nim next na następny element ,to robię podstawienie i że pierwszy teraz jest next ,chyba że next wskazuje na NULL to while już kończy pracę, bo koniec listy.Wydaje mi się to dość logiczne poruszanie po wskaźnikach.Natomiast co do 42 linii to żeby to się wysypało to lista musiałby być chyba pusta.Ale faktycznie nie pomyślałem o tym żeby zabezpieczyć na taki wypadek.

Reasumując nadal nie wiem dlaczego nie wypisuje wszystkiego po kolei :/

[C++] Lista jednokierunkowa

: 1 paź 2015, o 00:51
autor: Dakurels
Tak, ale nadpisujesz zmienną "pierwszy", przez co tracisz dostęp do początku listy. Po pierwszym dodaj pierwszy wskazuje na 1A, po drugim nadal na 1A (ponieważ następnik jest nullem), ale po trzecim dodaj wskaźnik przesuwa się już na 2B a po ostatnim dodaj przesuwa się na 3C, przez co tracimy dostęp do 1A i 2B. To co do funkcji dodaj.

Teraz funkcja wyswietl. Jak już wyżej napisałem wskaźnik pierwszy wskazuje na 3C, sprawdza jego nexta (4D) po czym wypisuje wartość i przesuwa się na 4D. 4D nie ma nexta, więc zawartość while już się nie wyświetli - stąd brak informacji o ostatnim elemencie na konsoli.

Mam nadzieję, że teraz trochę jaśniej opisałem

[C++] Lista jednokierunkowa

: 7 paź 2015, o 10:16
autor: csminus
Problem jest taki, że jeżeli nie robisz tego do szkoły to powinieneś użyć stl a nie wymyślać takie twory

[C++] Lista jednokierunkowa

: 7 paź 2015, o 14:43
autor: Igor V
Jakie wzory ?

[C++] Lista jednokierunkowa

: 7 paź 2015, o 16:09
autor: Dakurels
csminus pisze:Problem jest taki, że jeżeli nie robisz tego do szkoły to powinieneś użyć stl a nie wymyślać takie twory
Ale on nie chce tego używać, tylko to napisać. Ja sądzę, że napisanie choć raz listy wskaźnikowej albo vectora jest bardzo kształcące - zwłaszcza na początku nauki.

[C++] Lista jednokierunkowa

: 10 paź 2015, o 15:24
autor: csminus
A więc jak mówi kolega Dakurels, nie powinieneś operować na pierwszym elemencie listy gdy dodajesz kolejny, powinieneś to robić jedynie gdy dodajesz pierwszy element lub chcesz go usunąć, powinieneś stworzyć element tymczasowy którego użyjesz to przewijania listy.

Kod: Zaznacz cały

void list::add(string s){
    element *newele = new element;
    newele -> s = s;

    if(first){
        element *temp = first;
        while(temp -> next) temp = temp -> next;
        temp -> next = newele;
        newele -> next = 0;
    }
    else first = newele;
}