[C++] Lista jednokierunkowa

Awatar użytkownika
Igor V
Użytkownik
Użytkownik
Posty: 1605
Rejestracja: 16 lut 2011, o 16:48
Płeć: Mężczyzna
Lokalizacja: Polska
Podziękował: 18 razy
Pomógł: 604 razy

[C++] Lista jednokierunkowa

Post 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ć.
Dakurels
Użytkownik
Użytkownik
Posty: 291
Rejestracja: 16 paź 2009, o 18:31
Płeć: Mężczyzna
Lokalizacja: Kraków
Pomógł: 55 razy

[C++] Lista jednokierunkowa

Post 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
Awatar użytkownika
Igor V
Użytkownik
Użytkownik
Posty: 1605
Rejestracja: 16 lut 2011, o 16:48
Płeć: Mężczyzna
Lokalizacja: Polska
Podziękował: 18 razy
Pomógł: 604 razy

[C++] Lista jednokierunkowa

Post 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 :/
Dakurels
Użytkownik
Użytkownik
Posty: 291
Rejestracja: 16 paź 2009, o 18:31
Płeć: Mężczyzna
Lokalizacja: Kraków
Pomógł: 55 razy

[C++] Lista jednokierunkowa

Post 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
Awatar użytkownika
csminus
Użytkownik
Użytkownik
Posty: 45
Rejestracja: 29 lis 2014, o 13:06
Płeć: Mężczyzna
Lokalizacja: Lublin/Kraków/Warszawa
Pomógł: 3 razy

[C++] Lista jednokierunkowa

Post 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
Awatar użytkownika
Igor V
Użytkownik
Użytkownik
Posty: 1605
Rejestracja: 16 lut 2011, o 16:48
Płeć: Mężczyzna
Lokalizacja: Polska
Podziękował: 18 razy
Pomógł: 604 razy

[C++] Lista jednokierunkowa

Post autor: Igor V »

Jakie wzory ?
Dakurels
Użytkownik
Użytkownik
Posty: 291
Rejestracja: 16 paź 2009, o 18:31
Płeć: Mężczyzna
Lokalizacja: Kraków
Pomógł: 55 razy

[C++] Lista jednokierunkowa

Post 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.
Awatar użytkownika
csminus
Użytkownik
Użytkownik
Posty: 45
Rejestracja: 29 lis 2014, o 13:06
Płeć: Mężczyzna
Lokalizacja: Lublin/Kraków/Warszawa
Pomógł: 3 razy

[C++] Lista jednokierunkowa

Post 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;
}
ODPOWIEDZ