Miałem zamiar odpisać w poprzednim temacie, ale skoro jesteśmy już tutaj:
powiedzmy że mamy strukture:
Kod: Zaznacz cały
struct foo {
struct foo *next;
struct foo *prev;
char *data;
};
Jeśli masz zaalokowaną pamięć i powiedzmy wskaźnik do Twojej struktury:
to możesz się poruszać po niej w sposób następujący:
Kod: Zaznacz cały
(moj_wskaznik->next)->prev = moj_wskaznik // teraz wskaznik 'prev' nastepnej struktury wskazuje na tą strukture - bedziesz mogla wrocic do tej kiedy zechcesz
moj_wskaznik = moj_wskaznik->next; // przechodzimy do kolejnej przestrzeni
Znajdziesz się wtedy w kolejnej przestrzeni (kolejny węzeł struktury);
Potem, jeśli będziesz chciała przejść jeden poziom wstecz:
Oczywiście wiadomo, że musisz odpowiednio alokować pamięć dla swoich struktur (i odpowiednio ustawiać wskaźniki!), dlatego właśnie sugerowałem napisać funkcje, które będą robić to za Ciebie, przykładowo, dla mojej struktury
foo:
Kod: Zaznacz cały
struct foo *alokuj_wezel(struct foo *ostatni_wezel)
{
struct foo *nowy_wezel = malloc(sizeof(struct foo));
if (nowy_wezel == NULL) {
return NULL;
}
nowy_wezel->next = NULL;
nowy_wezel->data = NULL;
nowy_wezel->prev = ostatni_wezel;
if (ostatni_wezel == NULL) {
ostatni_wezel = nowy_wezel;
} else {
ostatni_wezel->next = nowy_wezel;
}
return nowy_wezel;
}
W wyniku wywolania tej funkcji z kontekstu:
Kod: Zaznacz cały
bar()
{
struct foo *moja_struktura;
// pierwsza alokacja
alokuj_wezel(moja_struktura);
// nastepne wezly
alokuj_wezel(moja_struktura);
}
Będziesz za każdym razem budować kolejne węzły struktury lub sam szkielet tej struktury (wreszcie nazwijmy to listą obustronnie łączoną).
Dorzuce też dla przykładu funkcję służącą zwolnieniu pamięci
całej listy:
Kod: Zaznacz cały
void zwolnij_liste(struct foo *lista)
{
struct foo *wezel;
for (wezel = lista; wezel != NULL; wezel = wezel->prev) {
free(wezel);
}
free(lista);
}
Uwierz, że warto sobie w ten sposób upraszczać życie, nawet dla takiego zadania jakie chcesz wykonać.
Ogolem Twoja petla chodząca po drzewie:
1. Przyjmijmy, że pobieramy dane z pliku.
2. Przyjmijmy, że spodziewamy się tylko 2 różnych znaków:
0 i
1
Kod: Zaznacz cały
char ch;
while ((ch = getc(wskaznik_do_pliku)) != EOF) {
switch (ch) {
case '1':
// Twoja czynność którą chcesz wykonać na drzewie
break;
case '0':
// Twoja czynność ktora chcesz wykonac na drzewie
break;
default:
break;
}
}