Usuwanie konkretnego elementu z listy - język C

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;
}
2

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:)

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