Usuwanie rekursywne z listy

0

Problem jest tego typu że próbuję usunąć z listy jedno kierunkowej wszystkie wystąpienia wartości x w tej liście mam coś takiego i nie dział proszę o pomoc kompilator to przepuścił ale później się zbuntował.
Cały program w załączniku
====To jest ta funkcja===

wsk usun_wszystkie_wskazane_rec(wsk *l,int y)
{
wsk usun;
if((*l)==NULL) return ;
if((*l)->x != y) return usun_wszystkie_wskazane_rec((*l)->nast,y);
if((*l)->x == y){
	usun=*l;
	(*l)=usun_wszystkie_wskazane_rec((*l)->nast,y);}
	
	free(usun);
	return l;

}
0

A zmieniasz gdzies przypisanie poprzedni_wsk->nast w przypadku usuniecia wsk?
Bo jesli tylko usuwasz noda, to masz "dziurę" w liście.

0

Typedef, typedef, typedef... i ciężko się połapać o co chodzi xD.
Funkcja usun_wszystkie_wskazane_rec oczekuje jako argument wskaźnika wsk na wskaźnik wsk elementu elem która jest strukturą el, a tymczasem w kodzie podajesz jej zmienną wsk. No i drugi błąd, w drugiej linijce wywołujesz return ale nic nie zwracasz a funkcja powinna coś zwracać np NULL. Poprawnie powinno wyglądać tak, przynajmniej na C::B, tj tak żeby działało:

wsk usun_wszystkie_wskazane_rec(wsk *l, int y)
{
    wsk usun;
    if((*l) == NULL) return nullptr;
    if((*l)->x != y)
        return usun_wszystkie_wskazane_rec(&(*l)->nast, y);
    if((*l)->x == y)
    {
        usun = *l;
        (*l) = usun_wszystkie_wskazane_rec(&(*l)->nast, y);
    }

	free(usun);
	return *l;
}

Dziwne że ci kompilator przepuścił, u mnie wystąpił też błąd z tym:

wsk q = malloc(sizeof(elem));

powinno być:
wsk q = (wsk)malloc(sizeof(elem));

0

czaffik coś tu nie gra bo on mi zwraca pustą listę to się pewno bierze z tego że *l po tym wszystkim wskazuje na koniec a ja bym chciała żeby tam w środku się pousuwało co trzeba a na koniec zwrócić "głowę" do tego, ja niestety nie wiem przy tych rekurencyjnych jak sobie "przechować" wsk na głowę ten na początku a w środku sobie wykonać operacje i niby zwracasz to samo ale nie.
xfin niestety nie rozumiem ja wg nie mam poprzednika

0

Zwróciłem uwagę na błędy kompilatora ale faktycznie zwróci pustą listę bo tak ta funkcja jest skonstruowana, zawsze na koniec zwróci NULL, a dalej do listy przypisujesz wynik tej funkcji. Nie wiem czy da radę przechowywać głowę wewnątrz funkcji rekurencyjnej, coś mi się wydaje że nie bardzo. Musiałbyś głowę przechować przed wywołaniem funkcji, ale jak zrobić taką funkcję to szczerze nie mam zielonego pojęcia.

0

Bez rekurencji będziesz miał coś a'la:

typedef struct node {
    struct node* next;
    int data;
} node;

typedef struct list {
    node* head;
    node* tail;
} list;

void remove_if(list* l, int saught_data) {
    node* current = l->head;
    node* prev = NULL;
    
    while (current) {
        if (current->data == saught_data) {
            node* remove = current;
            if (current == l->head) {
                l->head = current->next;
            } else {
                prev->next = current->next;
            }
            current = current->next;
            free(remove);
        } else {
            prev = current;
            current = current->next;
        }
    }
    //poniższe można wepchać tam wyżej, żeby nie jechać po całej liście, zostawiam to jako ćwiczenie dla czytelnika. ;)
    current = l->head;
    while (current && current->next) {
        current = current->next;
    }
    l->tail = current;
} 

Jak widać, ominąłem rekurencję, bo to niekoniecznie najlepszy pomysł. Stos nie jest z gumy - przy dużej liście rekurencyjne rozwiązanie może Ci się posypać. No ale jeśli kochasz rekurencję - przerabiaj do woli. ;)

0

Dziękuję wszystkim za sugestie niestety sposób rekursywny jest narzucony z góry walczę dalej XD

1 użytkowników online, w tym zalogowanych: 0, gości: 1