Jesli ktos z was zna jakis artykul z ktorego moge dowiedziec sie wiecej o liscie podczepianej i nauczyc sie ja tworzyc to poprosilbym o link, najlepiej do artykulu po polsku jesli nie to po angielsku.I mam tez pytanie czy lista podczepiana to to samo co rekursywna ?
Artykul o liscie podczepianej
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Hong Kong
nie spotkalam sie z okresleniem lista podczepiana (ani rekursywna...). byc moze chodzi ci o liste jednokierunkowa/dwukierunkowa i cykliczna? http://pl.wikipedia.org/wiki/Lista
- Rejestracja: dni
- Ostatnio: dni
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
No i Spartan pomyliles sie, mowiles ze po przeczytaniu tego wszystko stanie sie dla mnie jasne, przeczytalem 2 razy i nic nie jest dla mnie jasne, program z twojego linku jest inny niz ten z tego kodu:
#include <stdio.h>
#include <stdlib.h>
typedef struct element {
struct element *next;
unsigned long val;
} el_listy;
el_listy *first; /* To jest wskaznik first na strukture el_listy tak ? */
void dodaj_do_listy (el_listy *lista, unsigned long liczba)
{
el_listy *wsk, *nowy;
wsk = lista;
while (wsk->next != NULL)
{
wsk = wsk->next; /* Nie rozumiem jak dziala przesuwanie wskaznika, z tego co mysle to "wsk" to jest to el_listy *first tak ? a wiec jak to dziala el_listy *first = *wsk.next ? prosilbym o wyjasnienie jak dziala tutaj to przesuwanie. */
}
nowy =(el_listy*) malloc (sizeof(el_listy));
nowy->val = liczba;
nowy->next = NULL;
wsk->next = nowy;
}
void wypisz_liste(el_listy *lista)
{
el_listy *wsk=lista;
while( wsk != NULL )
{
printf ("%lu\n", wsk->val);
wsk = wsk->next;
}
}
int jest_pierwsza(el_listy *lista, int liczba)
{
el_listy *wsk;
wsk = lista;
while (wsk != NULL) {
if ((liczba%wsk->val)==0) return 0;
wsk = wsk->next;
}
return 1;
}
int main ()
{
unsigned long i = 3;
const unsigned long END = 1000;
first =(el_listy*) malloc (sizeof(el_listy));
first->val = 2; /* i tutaj te dwie linijki, ta i ta pod spodem z nextem... ten first->val i first-> next to bedzie to "wsk" uzywane w funkcjach tak ? w takim razie ktora ma wartosc */
first->next = NULL;
for (;i!=END;++i) {
if (jest_pierwsza(first, i))
dodaj_do_listy (first, i);
}
wypisz_liste(first);
return 0;
}
Przeczytalem ale dalej nie rozumiem jak dziala to przesuwanie wskaznika, moglby ktos przetlumaczyc mi to wyrazenie "wsk = wsk->next" ? nie rozumiem tego wyrazenia prosilbym o tlumaczenie oraz o co chodzi z tym pierwszym elementem, i wgl o co chodzi najpierw next ma wartosc null a w pierwszej funkcji program zawziecie wyszukuje wartosci null nexta, nie rozumiem w cale, link mi nic nie wyjasnia, prosilbym o dodatkowe wyjasnienia.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Hong Kong
Czego nie rozumiesz? Przeczytales zawartosc linka ktorego ci dalam?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
Tak i tego i tego co dal spartan nic mi nie swita, wkleje tutaj caly kod i wypisze czego dokladnie nie rozumiem
#include <stdio.h>
#include <stdlib.h>
typedef struct element {
struct element *next;
unsigned long val;
} el_listy;
el_listy *first; /* I co to jest wskaznik na cala strukture el_listy, i ma wartosc 2 tak ? bo potem bedzie first->val=2, czyli el_listy *first na poczatku ma wartosc 2 czy NULL jak next ? To pierwsza rzecz teraz w drugiej kolejnosci opisywania moich niejasnosci przejde do funkcji main. */
void dodaj_do_listy (el_listy *lista, unsigned long liczba)
{
el_listy *wsk, *nowy;
wsk = lista;
while (wsk->next != NULL)
{
wsk = wsk->next; /* Tutaj nie wiem po co to juz wgl, bo w funkcji jest_pierwsza wskaznikowi dalismy juz wartosc NULL tak ?*/
}
nowy =(el_listy*) malloc (sizeof(el_listy));
nowy->val = liczba; /* jesli dodamy liczbe do nowy.val bedzie ona zmieniona automatycznie w first.val ? Pozatym jak jedna zmienna "val" w strukturze el_listy przechowuje tyle liczb ? W ostatniej funkcji mam te same problemy co w tych.*/
nowy->next = NULL;
wsk->next = nowy;
}
void wypisz_liste(el_listy *lista)
{
el_listy *wsk=lista;
while( wsk != NULL )
{
printf ("%lu\n", wsk->val);
wsk = wsk->next;
}
}
int jest_pierwsza(el_listy *lista, int liczba)
{
el_listy *wsk; /* tutaj el_listy *first = el_listy *wsk - tak ? */
wsk = lista;
while (wsk != NULL) { /* i tutaj mam problem bo nie wiem jaka wartosc ma ten el_listy *wsk, jesli NULL to po co ten while */
if ((liczba%wsk->val)==0) return 0;
wsk = wsk->next; /* a tego kompletnie nie rozumiem, jak dziala to przesuwanie, ale opisze jak ja to widze i prosilbym o poprawe, wiec:
wsk = wsk->next wydaje mi sie ze jest rownowazne z: el_listy *wsk = el_listy *wsk->next - tak czy nie ? no bo teraz przypisalismy chyba wartosc NULL do "wsk" tak ? Chyba zadego przesuwania tu nie bylo tylko nadanie wsk wartosci NULL ktora ma next, tak ? teraz do funkcji dodaj_do_listy */
}
return 1;
}
int main ()
{
unsigned long i = 3;
const unsigned long END = 1000;
first =(el_listy*) malloc (sizeof(el_listy));
first->val = 2; / * tutaj first.val = 2 i first.next = NULL, a wiec el_listy *first jaka ma wartosc ? Oraz *first to byl wskaznik na strukture el_listy i teraz jest przekazywany nie jako wskaznik ale samo first do funkcji "jest_pierwsza" "dodaj_do_listy" oraz "wypisz_liste" tak ? I teraz chcialbym przejsc do funkcji "jest_pierwsza".*/
first->next = NULL;
for (;i!=END;++i) {
if (jest_pierwsza(first, i))
dodaj_do_listy (first, i);
}
wypisz_liste(first);
return 0;
}
Okej opisalem jak najlepiej umialem, bylbym b.wdzieczny za rzetelna pomoc i objasnienie.
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Pomorskie (Stare Kabaty)
Bo Ty w ogólnie nie rozumiesz jak działa( a przynajmniej ma działać ) taka lista.
To po kolei.
Hm, pare piw i szlugi jescze mi zostały, to co mi tam, napisze coś dłuższego.
el_listy *first; To wskaźnik na pierwszy element, czyli korzeń listy, od niego cała lista sie zaczyna, musimy wiedzieć gdzie jest początek, inaczej dostęp do listy byłby niemożliwy.
W funkcji main alokujesz przestrzeń dla tego jednego, konkretnego, korzeniowatego elementu, on jest początkiem, a dzieje sie to tutaj
first =(el_listy*) malloc (sizeof(el_listy));
first->val = 2; Tutaj natomiast przypisujesz korzeniowi wartość dwa (Uprzedzam pytanie, to nie jest właściwość listy że pierwszy element zawsze jest dwójką, po prostu taki program przekleiłeś, co szuka liczb pierwszych, pierwsza z liczb pierwszych to dwójeczka.)
first->next = NULL; Tutaj, ustawiamy wskaźnik na następny element na NULL, w praktyce oznacza to że nasz korzeń nie ma "przed sobą" nic, jest smutny i sam ( Ten wariant listy nie może "patrzyć" za siebie, jedynie w przód )
No to jedziemy dalej, tutaj for (;i!=END;++i) szukamy sprawdzamy liczby od i do END (Czy są pierwsze).
Tutaj if (jest_pierwsza(first, i)), sprawdzamy pierwszość, to chyba rozumiesz, a przesuwanie wygląda tak:
(Posłuże sie rysowaniem pokeboli :D, ten upośledzony inny pokebol to korzeń)
Czyli while (wsk != NULL) sprawdza czy aktualnie wskazywany pokebol nie jest ostatnim pokebolem, jeśli nie ma za nim innych, to jest.
Natomiast wsk = wsk->next; przesuwa poke-wskaźnik na następny element listy, i są to te strzałki na obrazku.
W przypadku jak zrozumiesz zrób taniec radości przy tym
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
Tak, wiem ze struct element *next to nastepny element a struct element *first to element pierwszy, nazwy sa mocno sugestywne, ale nie rozumiem dlaczego nimi sa, przeciez rownie dobrze nastepny element moglibysmy nazwac struct element *asdasdasd i to tez bylby nastepne a pierwszy moglby byc struct element *nananana i to tez bylby pierwszy, a wiec dlaczego one oznaczaja to co oznaczaja ? dlatego ze w strukturze stworzymy wskaznik na ta strukture to on automatycznie bedzie nastepnym jej elementem ?
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Pomorskie (Stare Kabaty)
Wyraźnie napisałem Ci to wyżej.
Musisz znać pierwszy element, powiedz mi w takim razie, jak chciałbyś przeiterować (przelecieć, przejść się, whateva) po liscie bez informacji gdzie ta lista sie zaczyna?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
przesuwania nie rozumiem, next dostalo wartosc NULL to po co przesuwac skoro next ma wartosc null ciagle ;c
- Rejestracja: dni
- Ostatnio: dni
Nie ciągle. NULLa ma na samym końcu, jest to swoisty wyznacznik końca listy.
Rada na przyszłość: jeśli nie rozumiesz jakiegoś zagadnienia, algorytmu, czegokolwiek -
weź kartkę, długopis i na podstawie kodu źródłowego wykonuj odpowiednie kroki.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
Ale w main od razu dajemy next wartosc null a przeciez next w sobie powinno miec adres struktury element chyba ? a wiec next ma w sobie adres do struktury element i przypisujemy mu wartosc null... nie rozumiem poza tym jak el_listy *first wskazuje na 1 element first wskazuje chyba na adres pamieci
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Pomorskie (Stare Kabaty)
Jest tam NULL bo jescze wtedy ten węzeł nie ma następcy.
Powiedz mi czy po pierwszym wywołaniu dodaj_do_listy dalej tam będzie NULL?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
Chwila, w dodaj_do_listy tworzymy nowy element i do obiektu val nowego elementu wpisujemy wartosc nowej liczby pierwszej a do elementu next wartosc null, ale wsk->next juz ma wartosc nowego elementu, a ten nowy element ma w sobie val o wartosci nowej liczby i next o wartosci null tak ?
- Rejestracja: dni
- Ostatnio: dni
- Lokalizacja: Pomorskie (Stare Kabaty)
Powiedzmy.
A potrafisz wyjaśnić dlaczego w nowym elementcie do next przypisujemy NULL?
BTW. Czy Ty jesteś studentem?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 172
while (wsk->next != NULL)
{
wsk = wsk->next; /* przesuwamy wsk aż znajdziemy ostatni element */
}
Przy pierwszym odwiedzeniu tego while'a wsk mialo wartosci val=2 i next=null wiec nie trzeba bylo przesuwac i przeszlo dalej, poszlismy dalej do wsk->next zostaly wprowadzone wartosci val=nowa pierwsza liczba i next->null, gdy drugi raz odwiedzamy ten while, wsk ma wartosci: val=2 i next=gdzie val=nowa liczba i next nexta=null, wiec przypisujemy wsk wartosc val znajdujacej sie w next i petla wykonuje sie znowu a teraz wsk ma juz w val wartosc val=nowa liczba i next=null, i petla sie konczy i wchodzimy znowu tam gdzie przypisujemy wsk->next nowa liczbe, potem znowu szukamy nastepnej liczby i znowu odwiedzamy while teraz nasz wsk ma tak jak wtedy wartosc val=2 i next=ktory ma wartosc val=druga z kolei liczba pierwsza a next nie ma wartosci null(tylko wartosc val=trzecia liczba pierwsza i next=null) wiec przypisujemy wsk wartosc val=druga liczba pierwsza i next=val=trzecia liczba pierwsza i next=null i wykonujemy znowu, teraz wsk ma wartosc val=druga(liczba pierwsza) i next= val=trzecia liczba i next =null czyli przypisujemy wsk ta wartosc i wchodzimy znowu, teraz wsk ma wartosc val=trzecia liczba pierwsza i next=null i petla sie konczy, Troche dlugo to opisalem ale dobrze czy zle ? ;p
btw.nie jestem.
- Rejestracja: dni
- Ostatnio: dni
Lista boli tylko za pierwszym razem.
Dorób do tego unit testy to wszystko wyjdzie.
- dodanie n elementów i sprawdzenie liczby elementów
- dodanie na początku, na końcu, w środku
- usunięcie na początku, na końcu, w środku
- odczytanie pierwszego, ostatniego, n-tego elementu
Frameworki do testowania w C (nie testowałem ich):
- MinUnit: http://www.jera.com/techinfo/jtns/jtn002.html
- Check: http://check.sourceforge.net/
- CUnit: http://cunit.sourceforge.net/
- CMocka: https://cmocka.org/
- CuTest: http://cutest.sourceforge.net/
- CppUTest: http://cpputest.github.io/
- cmockery: https://code.google.com/p/cmockery/
Pewnie ktoś kto programuje (więcej) w C będzie mógł podać coś konkretniej.