matematykaszkolna.pl
Lista jednokierunkowa. Mikołaj: Lista jednokierunkowa. Wiem,że to forum matematyczne, ale na pewno są też tutaj informatycy i tych prosiłbym o pomoc. Nie do końca czuję wskaźniki i mam problem z zadaniami z list. Czy ktoś mógłby mnie nakierować jak zrobić takie zadanie? Ogólnie mam jakieś podstawy i przedstawię swój pomysł na rozwiązanie, jeśli tylko ktoś napisze, że jest w stanie pomóc emotka Dana jest lista liniowa jednokierunkowa o adresie pierwszego elementu h zawierająca liczby całkowite o niepowtarzających się wartościach. Podaj algorytm usuwający element zawierający wartość x podaną przez użytkownika.
20 lut 18:35
20 lut 18:44
Saris: no to zapewne masz dana jakas strukture z polami wartosci i przejscia dalej. no to zrob funkcje o 2 argumentach node *&h, int x − gdzie node to jest ta twoja struktura budujaca listę wejściową , h wskaźnik na 1 element. Przekazujemy przez referencje, bo chcesz coś usunąć i mieć nową listę poza funkcją. x to wartosc usuwana. Wczesniej zrob sobie funkcje usun gdzie podajesz po prostu x i wywulujesz w niej tą która usuwa wlasnie od tego x'a). No funkcja główna wygląda tak, że poruszasz się po tej liście i porównujesz wartość x z wartością wagonika, na który patrzysz, jak są równe to usuwasz. I teraz masz kilka opcji, bo żeby coś usunąć w liście jednokierunkowej musisz mieć wskazanie na wcześniejszy wagonik, żeby go móc przepiąć dalej. Mianowicie, stworzenie wartownika na początku, i iterowanie się po jakimś znaczniku p−>next, że element, na który patrzysz jest za elementem na który wskazuje znacznik p. (to jest tylko przykładowa nazwa) albo robisz 2 znaczniki jeden za drugim iterujesz się oboma naraz, ale tu musisz wyifować sytuację na początku, bo nie wiadomo czy ten wcześniejszy np nie wskazuje już na dobrą wartośc, także polecam raczej wartownika. Uwagi: nie przekroczyć listy przesuwając się po niej, jak usuwasz element pierwszy musisz przepiąć wskaźnik h albo stworzyć jakiś tymczasowy, który trzyma początek listy, w ogóle to na początku sprawdzić czy lista nie jest pusta. Trochę na szybko pisałem, więc może być chaotyczne.
20 lut 18:55
Mikołaj: Dzięki jakubs za linka. Oczywiście korzystam z tej strony przy nauce emotka Zadanie jest bardzo podobne, tylko nie wiem co w moim przypadku dać w pętli while, jak ją zapisać... Nie potrafię zapisać jak dojść do poprzednika elementu o wartości x.
20 lut 18:58
Mikołaj: Dziękuję Saris. Postaram się zrozumieć, ale czuję, że najpierw będę musiał sięgnąć do lektury, bo kilka zwrotów było dla mnie nieznanych, np. lista z wartownikiem. Kolega przesłał mi takie rozwiązanie: p=h; if (h−>dane == x) { h = h−>nast; delete p; } else { w = h−>nast; while (w != NULL AND w−>dane != x) { w = w−>nast; p = p−>nast; } if ( w != NULL) { p−>nast = w−>nast; delete w; } }
20 lut 19:13
Mikołaj: I szczerze powiedziawszy nie rozumiem tego rozwiązania. Saris, według Ciebie jest ono poprawne?
20 lut 19:21
Dziadek Mróz: Mówisz o liście list<int>? Czy własnej zdefiniowanej?
20 lut 19:28
Mikołaj: Nie rozumiem pytania Słabo znam się na listach...dla mnie jest to po prostu zwykła lista jednokierunkowa.
20 lut 19:35
Dziadek Mróz: Informacji o tym jest pełno, co jakiś czas zaglądam na stronę: http://www.p-programowanie.pl/cpp/lista-jednokierunkowa-c/ Tu ładnie jest wszystko wyjaśnione.
20 lut 19:37
Saris: dobrze. W sumie to jest dość klarowne, ja trochę pogmatwałem, bo myślałem, o usuwaniu niewiadomej liczby elementów. Działa to tak: tworzysz wskaźnik, który wskazuje tam gdzie h. Jeśli już pierwszy element to ten szukany przesuwasz wskaźnik h dalej i usuwasz p (który wskazuje tam gdzie wczesniej był h − tj. 1 element) i koniec. Jeśli to nie szukany element to tworzysz w i przypinasz go za h. Tak, więc teraz masz kolejno wskazania p i na następny element w. Jeśli w nie wskazuje na koniec listy i w nie jest szukanym elementem przesuwasz te wskaźniki, aż któryś warunek zacznie być false. po wyjściu z pętli sprawdzasz czy to nie koniec listy, jeśli nie to znaczy, że znalazłeś element do usunięcia (w na niego wskazuje) p przepinasz za w, a w usuwasz. koniec brakuje return; na końcu i inicjalizacji, chyba, że masz wyżej. i dopisz sobie na początku if(!h) return; (lub if(h==NULL) return; (sprawdzisz czy lista jest pusta i wyjdziesz od razu jeśli jest) bo w sumie jak rozumiem, masz tylko usunąć element bez zwracania? Także funkcją jest typu void tylko pamiętaj o referencji, bo tak to usuniesz tylko kopię elementu w funkcji, a poza nią lista będzie nie zmieniona.
20 lut 19:45
Mikołaj: Dzięki Saris jeszcze raz. Bardzo mi pomogło Twoje wyjaśnienie. Jeszcze nie wszystko rozumiem tak jakbym chciał, ale z czasem może będzie lepiej emotka
20 lut 20:31
asdf: lecisz po liscie jesli aktualny−>next−>id == x, to aktualny−>next = aktualny−>next−>next i dalej bajeruejsz z przypadkami, polecam nie korzystac z gotowcow, jest troche z tym łamigówek przy innych strukturach i nie jest to takie proste Ale fajnie sie przy tym idzie rozwinąć i ogarnąć temat programowania.
21 lut 18:26
Dziadek Mróz: A no, tylko pamiętać trza o zwalnianiu pamięci emotka
21 lut 19:24
Mikołaj: Intuicyjnie to złapałem (chyba) emotka Teraz mam usunąć element przed elementem zawierającym wartość x. Gdyby ktoś sprawdził poprawność byłbym mega wdzięczny emotka Zakładam, że lista ma co najmniej dwa elementy. p = h−>nast if ( p−>dane ==x) { h = h−>nast; delete p; } else { w=h; z=p−>nast; while ( z != NULL AND z−>nast != x) { z = z −> nast; p = p −> nast; w = w −> nast; } if (z != NULL) { w −>nast = p−>nast; delete p; } }
21 lut 20:14
Trivial: Uruchamiasz w ogóle te programy, czy tak sobie piszesz?
21 lut 20:20
asdf: najprosciej: while(p−>next−>next−>id != x) { p=p−>next; } d = p; k = p−>next; d−>next = k−>next; delete p−>next; przetestuj to, tak z glowy.
21 lut 20:25
Mikołaj: Na razie tylko piszę sobie na kartce taki pseudokod... Dlaczego nie uruchamiam? Bo w poniedziałek muszę to zaliczyć, a jeszcze nigdy nie uruchamiałem listy i pewnie trochę czasu by mi to zajęło. W przyszłym tygodniu na spokojnie sobie zobaczę czy te programy działają w realu, teraz po prostu nie zdążę.
21 lut 20:26
Trivial: Napisałem kiedyś program do sprawdzania wycieków pamięci w prostych programach. Można sprawdzić czy wszystko jest dobrze usuwane. Jeśli chcesz mogę podesłać.
21 lut 20:26
Trivial: Przecież z uruchamianiem jest prościej. Sam sobie utrudniasz. emotka
21 lut 20:27
asdf: ogarnij listy, bez zrozumienia tego nie da się programować są gotowe "biblioteki", ale dobrze jest rozumieć czemu to tak działa, powodzenia.
21 lut 20:32
Saris: nie rozpatrujesz sytuacji kiedy musisz usunąć 1 element, chyba, że p wskazuje na wartownika wtedy to jest ok + jak nie będzie elementu do usunięcia "wpadniesz" do NULLa emotka.
21 lut 20:32
Mikołaj: Dzięki asdf. Czyli wygląda na to, że to co napisałem ma jakiś sens, bo Twoje jest podobne. Trivial, pewnie masz rację, bo uruchamiam i widzę czy działa...tylko jak mówię − nie potrafię w tym momencie tego uruchomić. Jeśli możesz podesłać ten program, to nie pogardzę, przyda się na pewno w przyszłości emotka
21 lut 20:35
Saris: Sprawdzanie list jest o tyle problematyczne, że musisz napisać osobne funkcje do tworzenia listy no i w zależności od zadania posortowaną albo nie, jak tak to czy rosnącą czy malejące + funkcje do wypisywania. Plus jest taki, że jak sobie zrobisz algorytm, w którym uwzględniasz każdą opcję to będziesz miał na przyszłość + to jest dobre ćwiczenie.
21 lut 20:36
Saris: albo korzystać z biblioteki, ale jak Trivial napisał, możesz korzystać z jej funkcji, ale wcale nie wiedzieć co one robią i jak działają . Ten komentarz byl do posta asdf.
21 lut 20:37
Mikołaj: Saris, napisałeś " jak nie będzie elementu do usunięcia "wpadniesz" do NULLa", czyli co mam u siebie poprawić i w którym momencie?
21 lut 20:46
asdf: im zna się więcej tym lepiej − można to sobie później dostosować do własnych potrzeb − a już nie raz jak pobierałem bibliotekę to musiałem sobie coś do niej dopisać − bo nigdy nie jest wszystko napisane na gotowe. Omijanie czegoś, bo coś jest trudne mija się z chęcią nauki programowania...
21 lut 20:50
Dziadek Mróz: Lista: − obiekt obecny − wskaźnik na kolejną listę Gdy ostatni element na liście to wskaźnik na kolejną listę jest NULL.
21 lut 23:16
Trivial: https://www.sendspace.com/file/d1m4b4 Kompilujemy tak (w zależności od architektury): http://pastebin.com/nQb0Lnxc g++ test.cpp libmemchkr−win32.a lub g++ test.cpp libmemchkr−win64.a
21 lut 23:39
Trivial: A wynik dla programu testowego jest taki: Memory leaks! (1 detected). test.cpp:6: 0x6467d0 (1.23 kB): 58 01 64 00 00 00 00 00 b0 71 4c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
21 lut 23:46
Mikołaj: Dziękuję Trivial. Teraz mam chwilę, to popróbuję uruchomić te listy emotka
25 lut 19:38