Lista jednokierunkowa i jej obsługa

0

Dzień dobry :)
Dziś zajmuję się zamieszczonym poniżej programem obsługującym listę jednokierunkową. Znajduje się w nim funkcja, która usuwa wybrany element z listy. Ale jeśli takie elementy są dwa, to usuwa jedynie pierwszy. Jak przerobić tą funkcję aby usuwała wszystkie elementy o podanej wartości?
Oto kod:

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

enum flaga {NIE, TAK};

struct element
{
    int var;						//zmienna typu int przechowujaca wartosc
    struct element *nastepny;		//wskaznik na nastepny element
};

// pierwszy -> element1 -> element2 -> element3 -> ... -> elementx -> ostatni
struct element *pierwszy = NULL;		//wskaznik na pierwszy element listy
struct element *ostatni = NULL;			//wskaznik na biezacy element listy


struct element* utworz_liste(int var)
{
    printf("Utworzenie listy z elementem poczatkowym o wartosci: %d\n",var);
    struct element *wsk = (struct element*)malloc(sizeof(struct element)); 			//alokacja pamieci na pierwszy element listy
    if(NULL == wsk)																	//w przypadku nieprzydzielenia pamieci na element listy
    {																				//funkcja zwraca NULL, co swiadczy o niepowodzeniu
        printf("Nieudana proba utworzenia pierwszego elementu listy!\n");			//tworzenia listy
        return NULL;
    }
    wsk->var = var;																	//przypisanie wartosci typu int do utworzonego elementu
    wsk->nastepny = NULL;															//aktualnie nie ma kolejnego elementu na liscie

    pierwszy = ostatni = wsk;														//utworzony element jest pierwszym elementem na liscie
    return wsk;																		//i jednoczesnie elementem biezacym
}


struct element* dodaj_do_listy(int var, enum flaga dodaj_na_koncu)
{
    if(NULL == pierwszy)
    {
        return (utworz_liste(var));													//jesli lista jest pusta to dodaj utworz pierwszy element
    }

    if(dodaj_na_koncu)																//wyswietlanie komunikatu gdzie bedzie dodany nowy element
        printf("Dodanie elementu listy na jej koncu o wartosci: %d\n",var);			//zgodnie z wartoscia przekazanego argumentu dodaj_na_koncu
    else																			//gdy dodaj_na_koncu == true to nowy element jest dodawany
        printf("Dodanie elementu listy na jej poczatku o wartosci: %d\n",var);		//na koncu listy.

    struct element *wsk = (struct element*)malloc(sizeof(struct element));			//alokacja pamięci na kolejny element listy
    if(NULL == wsk)																	//w przypadku nieprzydzielenia pamięci na element listy
    {																				//funkcja zwraca NULL, co swiadczy o niepowodzeniu
        printf("Nieudana proba utworzenia nowego elementu listy!\n");				//utworzenia nowego elementu listy
        return NULL;
    }
    wsk->var = var;																	//przypisanie wartosci typu int do utworzonego elementu
    wsk->nastepny = NULL;															//aktualnie nie ma kolejnego elementu na liscie

    if(dodaj_na_koncu)																//ustawienie odpowiednie nowego elementu na koncu
    {																				//lub na poczatku listy oraz ustawienie polaczen
        ostatni->nastepny = wsk;													//pomiedzy elementami w kazdym przypadku
        ostatni = wsk;
    }
    else
    {
        wsk->nastepny = pierwszy;
        pierwszy = wsk;
    }
    return wsk;																		//funkcja zwraca wskaznik do nowoutworzonego elementu
}


struct element* przeszukaj_liste(int var, struct element **poprzedni)
{
    struct element *wsk = pierwszy;													//zmienne pomocnicze w funkcji
    struct element *tmp = NULL;														//poszukiwanie zaczyna sie od pierwszego elementu na liscie
    int znaleziony = 0;

    printf("...Przeszukiwanie listy. Szukana wartosc: %d \n",var);

    while(wsk != NULL)
    {
        if(wsk->var == var)															//jesli szukana wartosc zostala znaleziona na liscie
        {																			//to dzialanie petli zostaje przerwane
            znaleziony = 1;
            break;
        }
        else
        {
            tmp = wsk;
            wsk = wsk->nastepny;
        }
    }

    if(1 == znaleziony)
    {
        if(poprzedni)																//jesli do funkcji przekazany jest adres wskaznika
            *poprzedni = tmp;														//do poprzedniego elementu wzgledem wyszukanego
        return wsk;																	//to jego wartosc jest ustawiana - wykorzystane w funkcji
    }																				//skasuj_wartosc_z_listy(...)
    else																			//funkcja zwraca wskaznik do struktury, ktora zwiera poszukiwana wartosc
    {
        return NULL;
    }
}


int skasuj_wartosc_z_listy(int var)
{
    struct element *poprzedni = NULL;												//zmienne pomocnicze w funkcji
    struct element *do_skasowania = NULL;

    printf("...Kasowanie wartosci: %d z listy elementow\n",var);

    do_skasowania = przeszukaj_liste(var,&poprzedni);								//znajdz pierwsza strukture zgodna ze wzorcem var,
    																				//która zostanie skasowana
	if(NULL == do_skasowania)
    {
        return -1;																	//jesli nie znaleziono poszukiwanej wartosci to funkcja zwraca -1
    }
    else
    {
        if(NULL != poprzedni)														//wylaczenie kasowanego elementu z listy
            poprzedni->nastepny = do_skasowania->nastepny;							//czyli poprzestawianie wskaznikow w elementach
																					//omijajac element kasowany
        if(do_skasowania == ostatni)												//w zaleznosci czy kasowany elemen znajduje sie:
        {																			//wewnatrz listy, na koncu listy lub na poczatku listy
            ostatni = poprzedni;
            ostatni->nastepny = NULL;
        }
        else if(do_skasowania == pierwszy)
        {
            pierwszy = do_skasowania->nastepny;
        }
    }

    free(do_skasowania);															//zwolnienie pamieci skasowanego elementu
    do_skasowania = NULL;															//"wyzerowanie" wskaznika

    return 0;
}


void wydrukuj_liste(void)
{																					//funkcja wypisuje elementy listy
    struct element *wsk = pierwszy;													//nadajac im "umowne" numery porządkowe
    int i=0;
    if(NULL == wsk)
    {
    	printf("Lista jest pusta!\n");
    }
	else
    {
	    printf("\n ------- Wydruk listy / Poczatek ------- \n");
	    while(wsk != NULL)
	    {
	        printf("%3d. %5d adres=%d\n",i,wsk->var,wsk);
	        wsk = wsk->nastepny;
	        i++;
	    }
	    printf("------- Wydruk listy / Koniec --------- \n");
	}
    return;
}

int main(void)
{
    int i = 0, res = 0;
    struct element *wsk = NULL;

    wydrukuj_liste();

    for(i = 100; i<105; i++)
        dodaj_do_listy(i,TAK);

    wydrukuj_liste();

    for(i = 40; i>35; i--)
        dodaj_do_listy(i,NIE);
    dodaj_do_listy(104, TAK);

    wydrukuj_liste();

    for(i = 100; i<105; i += 2)
    {
        wsk = przeszukaj_liste(i, NULL);
        if(NULL == wsk)
        {
            printf("Szukana wartosc: %d, nie zostala znaleziona na liscie elementow!\n",i);
        }
        else
        {
            printf("...Szukana wartosc: %d, zostala znaleziona!\n",wsk->var);
        }

        wydrukuj_liste();

		res = skasuj_wartosc_z_listy(i);
        if(res != 0)
        {
            printf("Wartosc: %d nie zostala skasowana z powodu braku jej na liscie!\n",i);
        }
        else
        {
            printf("...Wartosc: %d zostala skasowana z listy! \n",i);
        }

        wydrukuj_liste();
    }

    return 0;
}
 
2

Niech szuka i kasuje po całej długości listy.

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