Usuwanie konkretnego elementu z listy - język C

Odpowiedz Nowy wątek
2019-09-06 12:25
0

Napisałam funkcję, która ma za zadanie "usuwać" taki element z listy, który wskażemy. Ogólnie program działa dla wszystkich cyfr za wyjątkiem ostatniej ( każdą cyfrę którą wskażę usuwa, tylko jak wskażę ostatnią to program się zawiesza. Aha i jak jakaś cyfra się powtarza to też nie usuwa jej tyle razy ile się pojawiła,ale tylko raz. :/

Ogólnie da się to zrobić prościej i wiem, że rozwiązanie może wydawać się dziwne, tym bardziej , że chyba lepiej używać do tego free(), ale niestety prowadząca kazała tym sposobem.

Z góry dziękuję za poświęcony czas :)

typedef struct el_listy{
    int klucz;
    struct el_listy * nast;
}LISTA,*LISTAWSK;

void dodajMalejaco(int x,LISTAWSK g){
    LISTAWSK pom;;

    while(g->klucz>=x && g->nast!=NULL)g=g->nast;
    pom=(LISTAWSK)malloc(sizeof(LISTA));
    if(g->nast==NULL){
        pom->klucz=x;
        pom->nast=NULL;
        g->nast=pom;
    }
    else{
            pom->klucz=g->klucz;
            pom->nast=g->nast;
            g->klucz=x;
            g->nast=pom;
        }

}
void dodajZa(LISTAWSK glowa,int x){
    LISTAWSK pom=(LISTAWSK)malloc(sizeof(LISTA));
    while(glowa->nast!=NULL)glowa=glowa->nast;
    pom->klucz=x;
    pom->nast=NULL;
    glowa->nast=pom;

}
void dodajZaPierwszym(LISTAWSK glowa,int nowy){
    LISTAWSK pom;
    pom=(LISTAWSK)malloc(sizeof(LISTA));

    pom->klucz=nowy;
    pom->nast=glowa->nast;
    glowa->nast=pom;
}
void dodajPrzedPierwszym(LISTAWSK glowa,int nowy){
    LISTAWSK pom=(LISTAWSK)malloc(sizeof(LISTA));
    pom->klucz=glowa->klucz;
    pom->nast=glowa->nast;
    glowa->klucz=nowy;
    glowa->nast=pom;

}

void dodajPoKonkretnym(LISTAWSK glowa,int nowy,int ktory){
    LISTAWSK pom=(LISTAWSK)malloc(sizeof(LISTA));
    while(glowa->klucz!=ktory){
            glowa=glowa->nast;
        }
        pom->klucz=nowy;
        pom->nast=glowa->nast;
        glowa->nast=pom;
}

LISTAWSK newNode(int new_data){
    LISTAWSK new_node =(LISTAWSK) malloc(sizeof(LISTA));

    new_node->klucz  = new_data;
    new_node->nast =  NULL;

    return new_node;
}
void usunKonkretny(LISTAWSK glowa,int konkretny){
    LISTAWSK pom;
    while(glowa->klucz!=konkretny && glowa->nast!=NULL)glowa=glowa->nast;
    pom=glowa->nast;
    if(glowa->klucz==konkretny && glowa->nast!=NULL){
            //pom=glowa->nast;
            glowa->klucz=pom->klucz;
            glowa->nast=pom->nast;
    }
    else if(pom==NULL && glowa->klucz==konkretny){
        pom=glowa;
        glowa=pom->nast;
            while(glowa->nast!=NULL){
                    glowa=glowa->nast;
                    pom=pom->nast;
             }
        pom->nast=NULL;
    }

}
int main(){
    LISTAWSK glowa;
    int licznik;
    glowa = newNode(2);

    dodajMalejaco(1,glowa);
    dodajZa(glowa,3);
   dodajZaPierwszym(glowa,7);
    dodajPrzedPierwszym(glowa,2);

    puts(" ");
    printf("Wszystkie cyfry w liscie:\n");
    print(glowa);
    printf("\n Po usunieciu:");

    usunKonkretny(glowa,7);

    print(glowa);

    return 0;
}
edytowany 7x, ostatnio: Kasia Iks, 2019-09-06 13:13
pętle masz nie zabezpieczone przed wyczerpaniem całej listy, np w razie nie istniejącego następny. Pierwszy while powinien jeszcze sprawdzać !=NULL. Rzeczywiście jest coś nietypowego, np hojne serwowanie zmian w elementach listy. Element powinien być immutable, może z wyjątkiem pola nast - AnyKtokolwiek 2019-09-06 12:40
Daj wiecej kodu, żeby można oddtworzyć ten przypadek. - lion137 2019-09-06 12:40
dałam strukturę i wywołania ;) - Kasia Iks 2019-09-06 12:55
A funkcja dodaj? - lion137 2019-09-06 12:57
dodałam wszystkie które tutaj wywołuję - Kasia Iks 2019-09-06 13:08

Pozostało 580 znaków

2019-09-06 13:44

Szczerze mówiąc nazewnictwo Masz nieintuicyjne, i lepiej jest tworzyć wskaźnik do obiektu i go przesyłać, zamiast tego typedef. No i sama funkcja, trochę zawikłana:) Lepiej, imo, zrobić to z użyciem rekurencji (sama za nas załatwi, który element usunąć i jaki wskaźnik zachować):

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

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

void push(nodesList ** head, int payload) {
    nodesList* _node = malloc(sizeof(nodesList));
    _node->data = payload;
    _node->next = *head; 
    *head = _node;
}

nodesList * deleteNode (nodesList * head, int val) {
    if (NULL == head)
        return NULL;
    if (head->data == val) {
        nodesList * tmp;
        tmp = head->next;
        free(head);
        return tmp;
    }
    head->next = deleteNode(head->next, val);
    return head;
}

void printList(nodesList * head);

int main() {
    nodesList * head = NULL;
    push(&head, 1);
    push(&head, 2);
    push(&head, 3);
    printList(&*head); // -> 3, 2, 1
    head = deleteNode(head, 1);
    printList(&*head); // -> 3, 2
    return 0;
}

void printList(nodesList * head) {
    nodesList * tmp = head;
    while (tmp){
        printf("%d, ", tmp->data);
        tmp = tmp->next;
    }
    printf("\n");
}

Jeśli element jest do usunięcia, to nad nim "przeskakujemy", jeśli nie to przechodzimy dalej (linijka przedostatnia) i zwracamy. Usuwa też tylko jeden element. Do usuwania niepotrzebne jest free, ale ta instrukcja musi tam być, żeby zdealokować pamięc zarezerwowaną przez malloc - inaczej Masz wyciek pamięci i mały kotek gdzieś umiera:)


Dziękuję za rozwiązanie i wytłumaczenie - wiem, że jest zawikłany, ale to w większości wszystkie funkcje są na bazie kodu Pani Profesor ode mnie z uczelni i po prostu ostatnio jak napisałam niezrozumiały dla niej kod to nawet nie wysiliła się , żeby sprawdzić... Dlatego wszystko przerabiam pod jej strukturę (stąd typedef). Apropos samego free - wiem, ze to się tyczy głownie pamięci, ale jak ona cokolwiek usuwa to nigdy tego nie używa, właśnie nie wiem dlaczego :/ Dziękuję, funkcja się bardzo przydała i przerobiłam już na swoją, działa szybko i wzorowo ;) - Kasia Iks 2019-09-06 15:14
Prosze bardzo, wyrazy współczucia z powodu Pani Profesor:) - lion137 2019-09-06 15:17
hhaha, dziękuję - przydadzą się :D - Kasia Iks 2019-09-06 15:22

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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