• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[C++] Lista powiązana

Object Storage Arubacloud
0 głosów
744 wizyt
pytanie zadane 17 lutego 2018 w C i C++ przez AnastaZIuk Początkujący (330 p.)
edycja 17 lutego 2018 przez AnastaZIuk

Witam, mam pewien problem.

Nie mogę zrozumieć pewnej rzeczy związanej z przestawianiem wskaźników w liście jednokierunkowej, chciałbym o wytłumaczenie tego zagadnienia, a oto kod:

 

#include <iostream>
#include <cstdlib>
#include <windows.h>

using namespace std;

void usun_obiekt(string nazwa_obiektu);

struct Obiekt
{
    string nazwa;
    string polozenie;
    int ilosc;
    int masa;
    int moc;
    int indeks;
    Obiekt *nowy_obiekt;
};
Obiekt *dostepny_obiekty = NULL;

    Obiekt *generujObiekt(string nazwa, string polozenie, int ilosc, int masa, int moc, int indeks)
    {
        Obiekt *cos = new Obiekt;
        cos->nazwa = nazwa;
        cos->polozenie = polozenie;
        cos->ilosc = ilosc;
        cos->masa = masa;
        cos->moc = moc;
        cos->indeks = indeks;
        cos->nowy_obiekt = dostepny_obiekty;
        dostepny_obiekty = cos;
        return cos;
    }

int main()
{
    Obiekt *lista_obiektow; lista_obiektow = dostepny_obiekty;
    Obiekt *ten_obiekt;

    string nazwa;
    string polozenie;
    int ilosc;
    int masa;
    int moc;
    int indeks = 1;


    while(true)
    {
        cout << "Witaj uzytkowniku! Stworz obiekt :)"; Sleep(3000); system("cls");
        cout << "Nazwa obiektu: "; cin >> nazwa; if(nazwa == "stop") break;
        cout << "Polozenie obiektu: "; cin >> polozenie;
        cout << "Ilosc tego obiektu: "; cin >> ilosc;
        cout << "Masa tego obiektu: "; cin >> masa;
        cout << "Moc tego obiektu: "; cin >> moc;

        ten_obiekt = generujObiekt(nazwa, polozenie, ilosc, masa, moc, indeks);
        indeks++;
    }

    system("cls");
    lista_obiektow = dostepny_obiekty;  //Aktualizujemy liste obiektow
    cout << "+--------------------------------------------+\n\n                STATYSTYKI\n\n";
    while(lista_obiektow != NULL)
    {
        cout << "Obiekt: " << lista_obiektow->nazwa << " [" << lista_obiektow->indeks << "]\n\n";
        cout << "  *Polozenie obiektu: " << lista_obiektow->polozenie << "\n";
        cout << "  *Dostepna ilosc tego obiektu: " << lista_obiektow->ilosc << "\n";
        cout << "  *Masa tego obiektu: " << lista_obiektow->masa << "\n";
        cout << "  *Moc tego obiektu: " << lista_obiektow->moc << "\n";
        lista_obiektow = lista_obiektow->nowy_obiekt; cout << "\n\n";
    }
    cout << "+--------------------------------------------+\n\n"; string nazwa_usun;
    Sleep(8000); cout << "\n\n\nJaki element chcesz usunac?\nWpisz jego nazwe: ";
    cin >> nazwa_usun;
    usun_obiekt(nazwa_usun); cout << "\n\nA oto aktualna lista obiekow!"; Sleep(1500); cout << "\n\n\n";

    lista_obiektow = dostepny_obiekty;
    cout << "+--------------------------------------------+\n\n                STATYSTYKI\n\n";
    while(lista_obiektow != NULL)
    {
        cout << "Obiekt: " << lista_obiektow->nazwa << " [" << lista_obiektow->indeks << "]\n\n";
        cout << "  *Polozenie obiektu: " << lista_obiektow->polozenie << "\n";
        cout << "  *Dostepna ilosc tego obiektu: " << lista_obiektow->ilosc << "\n";
        cout << "  *Masa tego obiektu: " << lista_obiektow->masa << "\n";
        cout << "  *Moc tego obiektu: " << lista_obiektow->moc << "\n";
        lista_obiektow = lista_obiektow->nowy_obiekt; cout << "\n\n";
    }
    cout << "+--------------------------------------------+\n\n";


}


void usun_obiekt(string nazwa_obiektu)
{
    Obiekt *lista_obiektow;
    lista_obiektow = dostepny_obiekty;
    Obiekt *zapisz_tymczasowo;

    while(true)
    {
        lista_obiektow = lista_obiektow->nowy_obiekt;
        if(lista_obiektow->nowy_obiekt->nazwa == nazwa_obiektu)              //Dochodzimy do wskaznika, za ktorym jest obiekt, ktorego szukamy
        {

            // ---> Dlaczego nie mozna tak zrobic? 
            lista_obiektow = lista_obiektow->nowy_obiekt->nowy_obiekt;

            //zapisz_tymczasowo = lista_obiektow->nowy_obiekt;
            //lista_obiektow = lista_obiektow->nowy_obiekt->nowy_obiekt;
            //delete zapisz_tymczasowo->nowy_obiekt;
            break;   
        }

    }

}

 

Nie mogę zrozumieć w jaki sposób mam usunąć element z takiej listy, próbowałem już na różne sposoby, ale nie mogłem do tego dojść. Za każdym razem próbuję się dostać do pamięci, której już nie ma/nie mam do niej dostępu, ponieważ nie mogę tego dobrze ustawić. Czy mógłby mi ktoś podpowiedzieć, w jaki prawidłowo przestawić wskaźniki i wytłumaczyć mi pokrótce, dlaczego akurat tak? To miejsce znajduje się w warunku funkcji usun_obiekt(string nazwa_obiektu). Z góry dziękuję!

W poleceniu mam napisane (jest to polecenie do zadania, którym jest ten kod) tak: "(...) Funkcja usuwająca powinna przyjmować tylko element przeznaczony do skasowania. Czy taka funkcja jest łatwa do napisania i czy będzie szybka? Czy można ją uprościć albo przyspieszyć, umieszczając w niej dodatkowy wskaźnik do listy?"

Nie wiem czy dobrze rozumiem, ale autorowi chodziło o wskaźnik do poprzedniego elementu listy, mylę się? Ja coś próbowałem z zapisem elementu, który znajduje się idealnie przed elementem, który chcę usunąć, ale raczej nie o to chodzi, bo nie działało to wcale w dobry sposób :D 
 

3 odpowiedzi

0 głosów
odpowiedź 17 lutego 2018 przez Programista 22 Bywalec (2,270 p.)
Chyba używasz jeden wskaznik do każdej zmiennej. Czyli ta zmienna może się zmieniać z np. Adam do Północ.
komentarz 17 lutego 2018 przez AnastaZIuk Początkujący (330 p.)
Tak, tylko czy da radę w taki sposób przestawić wskaźniki i usunąć element czy będę musiał zaimplementować drugi wskaźnik, który będzie mi również wskazywać w każdym obiekcie na poprzedni obiekt?
komentarz 17 lutego 2018 przez Programista 22 Bywalec (2,270 p.)
A co się stanie jeżeli kliniesz "build and run"?
0 głosów
odpowiedź 17 lutego 2018 przez AnastaZIuk Początkujący (330 p.)

Wyskrobałem coś, co nie zatrzymuje mi programu, ale teraz działa to tak, że usuwa mi element wybrany ze środka, który chciałem, tylko, że usuwa również całą resztę elementów, które są za tym elementem usuwanym. Nie mogę tego dalej zrozumieć, czekam na podpowiedź :/

 

void usun_obiekt(string nazwa_obiektu)
{
    Obiekt *lista_obiektow;
    lista_obiektow = dostepny_obiekty;
    Obiekt *zapisz_tymczasowo;
    Obiekt *zapisz_przed_usunieciem;

    while(true)
    {
        lista_obiektow = lista_obiektow->nowy_obiekt;
        if(lista_obiektow->nowy_obiekt->nazwa == nazwa_obiektu)              //Dochodzimy do wskaznika, za ktorym jest obiekt, ktorego szukamy
        {
            zapisz_przed_usunieciem = lista_obiektow->nowy_obiekt->nowy_obiekt;
            lista_obiektow->nowy_obiekt = NULL;
            delete lista_obiektow->nowy_obiekt;
            lista_obiektow = zapisz_przed_usunieciem;

            break;
        }

    }
}

 

0 głosów
odpowiedź 18 lutego 2018 przez AnastaZIuk Początkujący (330 p.)

Udało mi się napisać dzisiaj coś, co działa, tylko nie jestem pewny, czy na pewno pozbywam się tego elementu, a zostaje on w pamięci. Jeśli ktoś miałby kiedyś ten sam problem co ja, to umieszczam kod, w jaki sposób udało mi się do tego dojść z wytłumaczeniem w komentarzach. A ja proszę o sprawdzenie tego, nie jestem w 100% pewny poprawności tego kodu.

Pozdrawiam :)

 

void usun_obiekt(string nazwa_obiektu)
{
    Obiekt *lista_obiekty = dostepny_obiekty;
    Obiekt *test = dostepny_obiekty;
    Obiekt *test2;

    while(true)
    {
        lista_obiekty = lista_obiekty->nowy_obiekt;
        
        if(lista_obiekty->nowy_obiekt->nazwa == nazwa_obiektu)
        {
            test = lista_obiekty;     //Ustawiamy oba wskazniki na miejsce przed elementem, ktory chcemy usunac
            test2 = lista_obiekty;
            
            test2 = test2->nowy_obiekt;                   //Jednym ze wskaznikow przechodzimy   do elemtu, ktory chcemy usunac
            test = test->nowy_obiekt->nowy_obiekt;      //Z kolei drugim przechodzimy do elemtu, ktory znajduje sie za elementem usuwanym
            lista_obiekty->nowy_obiekt = test;        //Teraz przestawiamy wskaznik (ten przed elementem usuwanym), aby wskazywal na element, ktory znajduje sie za elementem usuwanym
            delete test2;                           //Usuwamy element, ktory chcielismy usuanc

            break;
        }
    }
}

 

A i proszę nie przejmować się nazwami typu "test","test2", one służyły mi tylko po to, aby upewnić się czy to co chcę zrobić zadziała. Ich nazwy można podmienić, jeśli ktoś chciałby skorzystać :D

Podobne pytania

0 głosów
1 odpowiedź 281 wizyt
pytanie zadane 9 maja 2020 w C i C++ przez chomik1 Nowicjusz (140 p.)
0 głosów
1 odpowiedź 1,570 wizyt
pytanie zadane 14 listopada 2019 w C i C++ przez baromeister Nowicjusz (140 p.)
0 głosów
1 odpowiedź 958 wizyt
pytanie zadane 21 maja 2018 w C i C++ przez Sylwek4321 Nowicjusz (160 p.)

92,556 zapytań

141,404 odpowiedzi

319,561 komentarzy

61,942 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...