rottingham Temat założony przez niniejszego użytkownika |
» 2019-08-01 22:16:44 Ok.
A dlaczego w argumencie funkcji wypisz jest słowo kluczowe const? Czy to jest potrzebne do stworzenia dobrego rozwiązania? |
|
pekfos |
» 2019-08-01 22:20:29 Nie. Po prostu logiczne jest, że wypisywanie listy nie wymaga jej modyfikowania. |
|
rottingham Temat założony przez niniejszego użytkownika |
» 2019-08-21 20:55:44 Czy jest sensowne, żeby w struct stworzyć trzecią składową przechowującą adres ostatniego elementu? Próbuję jakoś w ten sposób, ale nie wychodzi mi. Tzn. kod dodaje element na koniec listy, ale w liście znajduje się tylko pierwszy i ostatni element. Czy ten kod da się jakoś dopieścić czy to kompletnie nie tędy droga? #include <iostream>
using namespace std;
struct Wezel { int liczba; Wezel * ogon; Wezel ** adres; };
typedef Wezel * Lista;
void utworz( Lista & lista ) { lista = nullptr; }
void dodajKoniec( int liczba, Lista & lista ) { Lista nowy = new Wezel; nowy->liczba = liczba; nowy->ogon = nullptr; nowy->adres = &( nowy->ogon ); if( !lista ) { lista = nowy; } else { *( lista->adres ) = nowy; } }
void wypisz( const Lista lista ) { if( lista ) { cout << lista->liczba << " "; wypisz( lista->ogon ); } }
void zniszcz( Lista & lista ) { while( lista ) { Lista tmp = lista; lista = lista->ogon; delete tmp; } lista = nullptr; }
int main() { int liczba; Lista lista; utworz( lista ); while( cin >> liczba && liczba ) dodajKoniec( liczba, lista ); wypisz( lista ); zniszcz( lista ); }
|
|
pekfos |
» 2019-08-21 21:16:28 Czy jest sensowne, żeby w struct stworzyć trzecią składową przechowującą adres ostatniego elementu? |
Może gdy rozważamy tylko dodawanie elementów do listy nie jest to kompletnie niepraktyczne, jednak wciąż nie powiedziałbym że jest to sensowne. Wezel ma już wszystko czego potrzeba, raczej powinieneś zmienić znaczenie Lista. Podpowiedź: Możesz potrzebować drugiego struct. |
|
|
rottingham Temat założony przez niniejszego użytkownika |
» 2019-08-26 13:25:59 Hemm... Udało mnie się napisać taki kod. Co myślicie o tym? Będę wdzięczny za wszelkie uwagi i wskazówki. #include <iostream>
using namespace std;
struct Wezel { int liczba; Wezel * ogon; };
struct Lista { Wezel * poczatek = nullptr; Wezel * koniec = nullptr; };
void dodajKoniec( Lista & lista, int liczba ) { Wezel * element = new Wezel; element->liczba = liczba; element->ogon = nullptr; if( !lista.poczatek ) { lista.poczatek = element; lista.koniec = element; } else { lista.koniec->ogon = element; delete lista.koniec; lista.koniec = nullptr; lista.koniec = element; } }
void wypisz( Lista lista ) { while( lista.poczatek ) { cout << lista.poczatek->liczba << " "; lista.poczatek = lista.poczatek->ogon; } }
void zniszcz( Lista & lista ) { while( lista.poczatek ) { Wezel * tmp = lista.poczatek; delete tmp; lista.poczatek = lista.poczatek->ogon; } lista.poczatek = nullptr; while( lista.koniec ) { Wezel * tmp = lista.koniec; delete tmp; lista.koniec = lista.koniec->ogon; } lista.koniec = nullptr; }
int main() { int liczba; Lista lista; while( cin >> liczba && liczba ) dodajKoniec( lista, liczba ); wypisz( lista ); zniszcz( lista ); }
|
|
pekfos |
» 2019-08-26 17:51:14 To w ogóle działa? Nie wygląda.. |
|
rottingham Temat założony przez niniejszego użytkownika |
» 2019-08-26 19:29:16 Jak mogę rozpoznać, że ten kod nie działa? Wrzucając tego maina: int main() { Lista lista1, lista2; dodajKoniec( lista1, 1 ); dodajKoniec( lista2, 2 ); dodajKoniec( lista1, 3 ); dodajKoniec( lista2, 4 ); wypisz( lista1 ); std::cout << '\n'; wypisz( lista2 ); zniszcz( lista1 ); zniszcz( lista2 ); }
otrzymuję na wyjściu: 1 3 2 4 W związku z tym program pozornie jest w stanie zrobić dwie niezależne listy... Zatem dlaczego on nie działa? |
|
pekfos |
» 2019-08-26 20:19:50 Ja skopiowałem Twój kod, podałem na wejście 1 2 3 4 5 6 0 i dostałem 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 11674768 11561008 11543872 11544368 11534672 itd.. Trochę formalność, bo jak pisałem: kod nawet nie wygląda poprawnie. Jaka logika stała za tym, że dodajKoniec() alokuje jeden węzeł i zwalnia inny? Mam teorię: chcesz zwolnić wszystkie wskaźniki jakie masz, a powinieneś zwalniać wszystkie alokacje jakie wykonujesz (w swoim czasie naturalnie). Z jakiego innego powodu byś implementował niszczenie listy 2 razy - raz zaczynając od początku i raz od końca? Robisz z dodania tego dodatkowego wskaźnika znacznie większy problem, niż jest wart. Wystarczy go tylko w jednym miejscu ustawiać i w drugim wykorzystywać. Oba miejsca są w tej samej funkcji. |
|
1 2 « 3 » 4 5 6 |