• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Usuwanie listy 2-kierunkowej cyklicznej rekurencyjnie - pilne (na 5 rano)

Object Storage Arubacloud
0 głosów
631 wizyt
pytanie zadane 13 września 2016 w C i C++ przez danielek110795 Użytkownik (820 p.)

Potrzebuje usunac liste 2-kierunkowa cykliczna rekurencyjnie ale nie wychodzi. Wklejam kod, należy poprawić funkcje removee żeby usuwała całą liste. Liczę na szybką pomoc bo potrzebuje to na zaraz :D

 

#include <stdio.h>
#include <stdlib.h>

struct listnode {
    int data;
    struct listnode *next, *previous;
} *listpointer;

struct listnode *create (int data)
{
    struct listnode *first = (struct listnode*)malloc(sizeof(struct listnode));
    if (first)
    {
        first->data=data;
        first->next=first->previous=first;
    }
    return first;
};

struct listnode *findmin (struct listnode *listpointer)
{
    struct listnode *start, *result;
    start=result=listpointer;
    int min = listpointer->data;
    do {
        if (min>listpointer->data)
        {
            min = listpointer -> data;
            result = listpointer;
        }
        listpointer = listpointer -> next;
    }while (listpointer!=start);
    return result;
};

struct listnode *findnext (struct listnode *listpointer, int data)
{
    listpointer=findmin(listpointer);
    struct listnode *start = listpointer;
    do {
        if (listpointer->data>data)
            break;
        listpointer=listpointer->next;
    }while (listpointer!=start);
    return listpointer;
};

void add (struct listnode*listpointer, int data)
{
    if (listpointer)
    {
        struct listnode *newnode = (struct listnode*)malloc(sizeof(struct listnode));
        if (newnode)
        {
            newnode->data=data;
            listpointer = findnext(listpointer, data);
            newnode->next=listpointer;
            newnode->previous=listpointer->previous;
            listpointer->previous->next=newnode;
            listpointer->previous=newnode;
        }
    }
}

struct listnode *deletenode (struct listnode *listpointer, int data)
{
    if (listpointer)
    {
        listpointer = findnext(listpointer, data);
        listpointer = listpointer ->previous;
        if (listpointer->data==data && listpointer==listpointer->next)
        {
            free(listpointer);
            return NULL;
        }
        else
            if (listpointer->data==data)
            {
                struct listnode *next = listpointer -> next;
                listpointer->previous->next = listpointer->next;
                listpointer->next->previous = listpointer->previous;
                free(listpointer);
                listpointer = next;
            }
    }
    return listpointer;;
};

void wypisz (struct listnode *listpointer)
{
    listpointer = findmin(listpointer);
    struct listnode *start = listpointer;
    do {
        printf("%4d", listpointer->data);
        listpointer = listpointer ->next;
    } while (listpointer != start);
}

void removee (struct listnode **listpointer)
{
    if (*listpointer)
    {
        struct listnode *start=*listpointer;
        if (*listpointer != start)
        {

            removee(&(*listpointer)->next);
            free(*listpointer);
        }
    }
}

int main()
{
    listpointer = create(4);
    add(listpointer, 6);
    add(listpointer, 0);
    add(listpointer, 38);
    add(listpointer, 2);
    wypisz(listpointer);
    puts("");
    listpointer = deletenode(listpointer, 77);
    listpointer = deletenode(listpointer, 2);
    listpointer = deletenode(listpointer, 0);
    listpointer = deletenode(listpointer, 38);
    wypisz(listpointer);
    puts("");
    removee(&listpointer);
    wypisz(listpointer);
    puts("");
    return 0;
}

 

2 odpowiedzi

0 głosów
odpowiedź 13 września 2016 przez Szykem2 Nałogowiec (29,510 p.)
struct listnode *start=*listpointer;
if (*listpointer != start)

Nie uważasz, że te dwie linie(103-104) są trochę nielogiczne? Najpierw przypisujesz jednej zmiennej wartość drugiej, a potem kluczowy moment w tej funkcji jest wywoływany jeśli są różne, czyli nigdy nie jest wykorzystywana rekurencja.

komentarz 13 września 2016 przez danielek110795 Użytkownik (820 p.)
Poprawiłem na "==" i teraz program przestał działać.
komentarz 13 września 2016 przez Szykem2 Nałogowiec (29,510 p.)

Skoro teraz wywołuje się za każdym razem nie sądzisz, że lepiej usunąć tego ifa?

A co do programu to po nieco głębszej analizie mogę tylko stwierdzić, że logika jest zepsuta. Nigdzie nie widzę wartownika w postaci NULL'a, przez co nie jest możliwe zrobienie tego w łatwy sposób. Elementy stają się zapętlone i po usunięciu jednego wraca się ponownie do tego samego, który już został usunięty i wywala segfaulta. (Dodaj w linii 106 printf("%d\n",(*listpointer)->data); i zobacz co się dzieje). Nie jestem w stanie pomóc z taką logiką to ją trzeba poprawić w pierwszej kolejności.

Najpoważniejszy błąd to brak NULL'i. Nie ma po czym się orientować czy jesteśmy na liście czy już wyszliśmy poza nią.

Jeżeli lista ma być posortowana to po co funkcja szukająca minimum. Minimum zawsze musi być wskazywane przez head.

Poczytaj o listach i musisz przerobić tą logikę. LINK

komentarz 14 września 2016 przez danielek110795 Użytkownik (820 p.)
O to chodzi w liście cyklicznej, że nie ma NULLa i na takiej liście ja muszę to zrobić :P do tego co jest po prostu mam dopisać tą funkcję bez modyfikacji innych :)
0 głosów
odpowiedź 13 września 2016 przez damianMg4 Użytkownik (740 p.)

Masz problem z zatrzymaniem rekurencji, popraw funkcje wyświetlającą by sprawdzała przypadek gdy listpointer jest nullem

void removerek(struct listnode *ptr)
{
    if (ptr)
    {
        if(ptr->next!=listpointer)
            removerek(ptr->next);
        free(ptr);
    }
}

void removee (struct listnode *ptr)
{
    removerek(ptr);
    listpointer=NULL;
}

 

Podobne pytania

0 głosów
0 odpowiedzi 376 wizyt
0 głosów
1 odpowiedź 2,948 wizyt
pytanie zadane 16 kwietnia 2023 w C# przez Whyyy Nowicjusz (240 p.)
0 głosów
1 odpowiedź 267 wizyt
pytanie zadane 31 października 2021 w C i C++ przez letmestay Użytkownik (520 p.)

92,572 zapytań

141,422 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...