Opis
Lista jednokierunkowa daje możliwość grupowania dowolnej liczby elementów. Jedynym ograniczeniem dla niej jest ilość dostępnej pamięci. Jak jej nazwa wskazuje można ją przeglądać tylko w jedną stronę tzn, od początku do końca.
W celu jej budowy wykorzystuje się dwa typy komórek pamięci. Jeden z nich zawiera wskaźnik do początku oraz do końca listy. Drugi typ natomiast zawiera pole z wartością oraz wskaźnik na kolejny element z listy.
Działanie jest dosyć proste. Jeżeli na liście nie znajdują się żadne informacje to występują dwa wskaźniki do wartości typu NULL. Jest on pewnym adresem, nie koniecznie równym zero, na który żadna z występujących zmiennych nie będzie wskazywać.
Czyli każdy z elementów listy będzie się składać z wartości oraz wskaźnika na kolejny element.
Konstruktor mógłby wyglądać w następujący sposób:
Struktura powinna zawierać definicję poszczególnych składowych. Kolejnym elementem jest wskaźnik na następny element listy. Ostatnimi elementami są konstruktory powiązane z struktura.
Na liście można dokonywać następujących operacji:
Dodawanie elementu do listy, po czym następuje segregowanie elementów i sprawdzanie czy już nie ma takiego samego na liście:
Poniżej pojedyncza funkcja pozwalająca na umieszczenie elementu na początku listy:
Dodawanie elementu w środku lub na końcu listy:
Wyszukiwanie produktu:
Wypisanie szukanych elementów:
Usuniecie zadanego elementu:
Można te funkcje uprościć i usunąć pierwszy z listy poprzez wywołanie następującej funkcji:
Usuwanie całej listy:
Bibliografia
Konstruktor mógłby wyglądać w następujący sposób:
- struct Produkt
- {
- string Nazwa;
- string Opis;
- int ID;
- float Cena;
- //wskazanie na kolejny element z listy
- Produkt *nastepny;
- //Stworzony konstruktor
- Produkt()
- {
- // wczytujemy dane
- cout << "Nazwa - ";
- cin >> Nazwa;
- cout << "Opis - ";
- cin >> Opis;
- cout << "ID produktu - ";
- cin >> ID;
- cout << "Cena - ";
- cin >> Cena;
- //wskazniki ustawiamy na NULL
- nastepny = NULL;
- }
- void wypisz()
- {
- cout << "Nazwa - " << Nazwa << "Opis - " << Opis << "ID produktu - " << ID << "Cena - " << Cena << endl;
- }
- };
Struktura powinna zawierać definicję poszczególnych składowych. Kolejnym elementem jest wskaźnik na następny element listy. Ostatnimi elementami są konstruktory powiązane z struktura.
Na liście można dokonywać następujących operacji:
Dodawanie elementu do listy, po czym następuje segregowanie elementów i sprawdzanie czy już nie ma takiego samego na liście:
- void DodajProdukt(Produkt **poczatek)
- {
- //Tworzenie nowego produktu
- Produkt *nowa;
- nowa = new Produkt;
- //Zdefiniownaie pomocniczych wskazników
- Produkt *zmiennapomocnicza = (*poczatek);
- Produkt *zmiennapomocnicza2 = NULL;
- // dopoki nie wyszlismy za liste i nazwisko na liscie jest przed nowym nazwiskiem poruszamy sie dalej
- while (zmiennapomocnicza != NULL && (zmiennapomocnicza->Nazwa).compare(nowa->Nazwa) == -1)
- {
- //Wskazanie na poprzedni element
- zmiennapomocnicza2 = zmiennapomocnicza;
- zmiennapomocnicza = zmiennapomocnicza -> nastepny;
- }
- //Produkt o takiej nazwie znajduje się juz na liscie
- if (zmiennapomocnicza != NULL && (zmiennapomocnicza->Nazwa).compare(nowa->Nazwa) == 0)
- {
- cout << "Produkt" << nowa->Nazwa << " juz istanieje w wizytowniku\n";
- //Usunięcie nowego produktu
- delete nowa;
- }
- //Nowy element znajdzie sie na poczatku listy
- else if ((*poczatek) == NULL || (zmiennapomocnicza == (*poczatek) && (zmiennapomocnicza->Nazwa).compare(nowa->Nazwa) == 1))
- {
- nowa->nastepny = (*poczatek);
- (*poczatek) = nowa;
- }
- //Element zostanie dodany w innym miejscu listy
- else
- {
- zmiennapomocnicza2 -> nastepny = nowa;
- nowa -> nastepny = zmiennapomocnicza;
- }
- }
Poniżej pojedyncza funkcja pozwalająca na umieszczenie elementu na początku listy:
- int DodajNaPoczatek(Produkt **poczatek)
- {
- Produkt *nowa;
- nowa = new Produkt;
- Produkt *zmiennapomocnicza = (*poczatek);
- Produkt *zmiennapomocnicza2 = NULL;
- zmiennapomocnicza->Nazwa;
- if (nowa==NULL)
- {
- cout << "Brak wolnej pamieci";
- return 1;
- }
- nowa->nastepny = (*poczatek);
- (*poczatek) = nowa;
- return 0;
- }
Dodawanie elementu w środku lub na końcu listy:
- int DodajZaBiazacy(Produkt **poczatek)
- {
- Produkt *nowa;
- nowa = new Produkt;
- Produkt *zmiennapomocnicza = (*poczatek);
- Produkt *zmiennapomocnicza2 = NULL;
- zmiennapomocnicza->Nazwa;
- if (nowa==NULL)
- {
- cout << "Brak wolnej pamieci";
- return 1;
- }
- zmiennapomocnicza2 -> nastepny = nowa;
- nowa -> nastepny = zmiennapomocnicza;
- return 0;
- }
Wyszukiwanie produktu:
- void SzukajProduktu(Produkt *poczatek, string szukany)
- {
- //Przeszukiwanie listy element po elemencie, do mommentu znalezienia pasujacego lub
- //zakonczenia listy
- do
- {
- poczatek = poczatek->nastepny;
- }while(poczatek != NULL && (poczatek->Nazwa).compare(szukany) != 0);
- if (poczatek == NULL)
- {
- cout << "Nie znaleziono produktu " << szukany << endl;
- }
- else
- {
- poczatek->wypisz();
- }
- }
Wypisanie szukanych elementów:
- void WypiszProdukt(Produkt *poczatek)
- {
- cout << "Produkty zdefioniowane w liscie: \n";
- //Perla dziala az do konca listy
- while(poczatek != NULL)
- {
- poczatek->wypisz();
- poczatek = poczatek->nastepny;
- }
- }
Usuniecie zadanego elementu:
- bool UsunProdukt(Produkt **poczatek, string UsuwanyProdukt)
- {
- //Lista nie zawiera elementow
- if (*poczatek == NULL)
- {
- return false;
- }
- //Pomocnicze elementu
- Produkt *zmiennapomocnicza = (*poczatek), *zmiennapomocnicza2 = NULL;
- while(zmiennapomocnicza != NULL && (zmiennapomocnicza->Nazwa).compare(UsuwanyProdukt) != 0) // dopoki nie znajdziemy wizytowki z podanym nazwiskiem lub nie przeszukamy calego wizytownika
- {
- zmiennapomocnicza2 = zmiennapomocnicza;
- zmiennapomocnicza = zmiennapomocnicza->nastepny;
- }
- //Nie ma nazwiska na liscie
- if (zmiennapomocnicza == NULL)
- {
- return false;
- }
- else if (zmiennapomocnicza == (*poczatek))
- {
- (*poczatek) = (*poczatek)->nastepny;
- delete zmiennapomocnicza;
- }
- //Usuniecie ze srodka lub konca listy
- else
- {
- zmiennapomocnicza2->nastepny = zmiennapomocnicza->nastepny;
- delete zmiennapomocnicza;
- }
- return true;
- }
Można te funkcje uprościć i usunąć pierwszy z listy poprzez wywołanie następującej funkcji:
- void UsunPoczatek(Produkt *&poczatek)
- {
- Produkt *nowa;
- nowa = new Produkt;
- poczatek = nowa->nastepny;
- free(nowa);
- }
Usuwanie całej listy:
- void UsunWszystkie(Produkt *&poczatek)
- {
- Produkt *nowa;
- while (poczatek != NULL)
- {
- nowa = poczatek;
- poczatek = nowa->nastepny;
- free(nowa);
- }
- }
Bibliografia
[1] Algorytmy i złożoności Wykład 3. Listy jednokierunkowe
[2] Algorytmy, struktury danych i techniki programowania, Wróblewski, Wyd 3