Funkcja usuwania głowy w liście.

0

Cześć mam problem z funkcja usuwania pierwszego elementu w liscie. Zadanie polega na usunięciu całego elementu listy w momencie jeśli wiek podanej osoby jest większy od założonego.
Poniżej przesyłam kod struktury:

struct Slista
{
	string imie;
	string nazwisko;
	int wiek;
	Slista* wsk_nastepny;
};

Oraz kod funkcji:

void usun_element(Slista* adres, int n)
{
	Slista* aktualny, * poprzedni, * schowek;
	aktualny = adres;
	poprzedni = NULL;
	while (aktualny != NULL)
	{
		if (10 < aktualny->wiek)
		{
			schowek = aktualny;
			if (aktualny == adres)
			{
				adres = adres->wsk_nastepny;
			}
			else
			{
				poprzedni->wsk_nastepny = aktualny->wsk_nastepny;
			}
			aktualny = aktualny->wsk_nastepny;
			delete schowek;
		}
		else
		{
			poprzedni = aktualny;
			aktualny = aktualny->wsk_nastepny;
		}
	};
};

W celach testowych tej funkcji założyłem że powinny być usuwane wszystkie elementy które są wieksze od 10

if (10 < aktualny->wiek)

Funkcja działa bez problemu jeśli są usuwane elementy za pierwszym elementem listy. Problem pojawia się w momencie usuwania pierwszego elementu, w tym przypadku jeśli pierwszy element jest większy od 10. Czy ktoś może widzi gdzie popełniam błąd ?

Na samym dole wrzucam cały kod programu:

#include <iostream>
#include <string>

using namespace std;

struct Slista
{
	string imie;
	string nazwisko;
	int wiek;
	Slista* wsk_nastepny;
};

Slista *utworz_liste(int);
void drukuj_liste(Slista*, int);
int Wiek_przedostatniej(Slista*, int);
void usun_element(Slista*,int);
void kasuj_liste(Slista*);

int main()
{	
	int n;

	//Petla odpowiedzidalna za wartosc n wczytywanych danych > 0
	do
	{
		cout << "Podaj n ";
		cin >> n;
	} while (n <= 0);

	Slista* glowa;
	glowa = utworz_liste(n);
	drukuj_liste(glowa, n);		
	usun_element(glowa, n);
	drukuj_liste(glowa, n);
	kasuj_liste(glowa);

	
	system("pause");
	return 0;
}
Slista *utworz_liste(int n)
{
	Slista* glowa, * aktualny, * poprzedni;
	string p_imie, p_nazwisko;
	int p_wiek;

	aktualny = NULL;
	poprzedni = NULL;
	glowa = poprzedni;
	for (int i = 0; i < n; i++)
	{
		poprzedni = aktualny;
		aktualny = new Slista;
		cout << "Podaj imie do wstawienia ";
		cin >> p_imie;
		cout << "Podaj nazwisko do wstawienia ";
		cin >> p_nazwisko;
		cout << "Podaj wiek do wstawienia ";
		cin >> p_wiek;
		aktualny->imie = p_imie;
		aktualny->nazwisko = p_nazwisko;
		aktualny->wiek = p_wiek;
		aktualny->wsk_nastepny = NULL;
		if (poprzedni == NULL)
		{
			glowa = aktualny;
		}
		else
		{
			poprzedni->wsk_nastepny = aktualny;
		}
	}
	return glowa;
}
void drukuj_liste(Slista* adres, int n)
{
	int licznik = 1;
	while (adres != NULL)
	{
		cout << "Twoj " << licznik++ << " element listy. ";
		cout << "Imie: " << (*adres).imie << " ";
		cout << "Nazwisko: " << (*adres).nazwisko << " ";
		cout << "Wiek: " << (*adres).wiek << " ";
		adres = adres->wsk_nastepny;
		cout << endl;
	};
};
int Wiek_przedostatniej(Slista* adres, int n)
{
	int ile_wiek;
	if (n >= 1)		// Sprawdzanie czy jest wystarczajaca ilosc elementow w liscie
	{
		for (int i = 0; i < n - 1; i++)
		{
			ile_wiek = adres->wiek;
			adres = adres->wsk_nastepny;
		}
		cout << endl << "Wiek przedostatniej osoby na liscie wynosi = " << ile_wiek << endl;
	}
	return ile_wiek;
}
void usun_element(Slista* adres, int n)
{
	Slista* aktualny, * poprzedni, * schowek;
	aktualny = adres;
	poprzedni = NULL;
	while (aktualny != NULL)
	{
		if (10 < aktualny->wiek)
		{
			schowek = aktualny;
			if (aktualny == adres)
			{
				adres = adres->wsk_nastepny;
			}
			else
			{
				poprzedni->wsk_nastepny = aktualny->wsk_nastepny;
			}
			aktualny = aktualny->wsk_nastepny;
			delete schowek;
		}
		else
		{
			poprzedni = aktualny;
			aktualny = aktualny->wsk_nastepny;
		}
	};
};
void kasuj_liste(Slista* adres)
{
	Slista* schowek;
	schowek = adres;
	while (adres)
	{
		schowek = adres->wsk_nastepny;
		delete adres;
		adres = schowek;
	}
};

1

Twoja funkcja nie obsługuje poprawnie przypadku, gdy wskaźnik na poprzedni element jest null - em (gdy usuwamy głowę listy). Tutaj:
https://www.cs.bu.edu/teaching/c/linked-list/delete/
jest prawidłowa implementacja listDelete.

0
void usun_element( Slista*& adres , int wiek )
{
    Slista* current {adres};
    Slista* previous {nullptr};

    while( current != nullptr )
    {
        if( current->wiek > wiek )
        {
            Slista* to_delete {current};
            if( previous != nullptr )
            {
                previous->wsk_nastepny = current->wsk_nastepny;
            }

            current = current->wsk_nastepny;
            if( adres == to_delete ) adres = current;
            delete to_delete;
        }
        else
        {
            previous = current;
            current = current->wsk_nastepny;
        }

    };
};
0
lion137 napisał(a):

Twoja funkcja nie obsługuje poprawnie przypadku, gdy wskaźnik na poprzedni element jest null - em (gdy usuwamy głowę listy). Tutaj:
https://www.cs.bu.edu/teaching/c/linked-list/delete/
jest prawidłowa implementacja listDelete.

Dziekuje za pomoc !!
Po poprawkach napisalem taką funkcje:

void usun_element(Slista** adres, int n)
{
	Slista* aktualny, * poprzedni;
	aktualny = *adres;
	poprzedni = NULL;
	while (aktualny != NULL)
	{
		if (aktualny->wiek > 10)
		{
			if (poprzedni == NULL)
			{
				*adres = aktualny->wsk_nastepny;
			}
			else
			{
				poprzedni->wsk_nastepny = aktualny->wsk_nastepny;
			}
			delete aktualny;			
			return;
		}
		poprzedni = aktualny;
		aktualny->wsk_nastepny;
	}	
};

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