Najprostszymi dynamicznymi strukturami, które poznaliśmy, są stos i kolejka. Obydwie implementować można za pomocą różnych mechanizmów. Jedno z najprostszych rozwiązań, które służy zazwyczaj do wyjaśnienia działania tych struktur, to użycie statycznej lub dynamicznej tablicy. Jednak nie jest to rozwiązanie w pełni dynamiczne, ponieważ użycie tablic wymaga podania maksymalnej liczby przechowywanych w strukturze elementów. Aby uzyskać w pełni dynamiczne struktury stosu i kolejki, wykorzystuje się listy.

Stos

Przypomnijmy, że stos to liniowa struktura typu LIFO (ang. Last‑In, First‑Out – ostatni na wejściu, pierwszy na wyjściu), która obsługuje dwie podstawowe operacje, tj. odkładanie i zdejmowanie danych. Dodatkowe działania, które wykonuje się na stosie, to odczytywanie wierzchołka stosu, czyli ostatniego odłożonego elementu, bez usuwania go, oraz ewentualnie sprawdzanie rozmiaru stosu, czyli liczby odłożonych elementów.

Biorąc podane warunki pod uwagę, do implementacji stosu wystarczy jednokierunkowa lista niecykliczna. Elementami tej listy będą węzły zawierające dane, np. liczby, oraz – w przypadku listy jednokierunkowej – referencjareferencjareferencja na element następny. Do zdefiniowania węzła użyjemy klasyklasaklasy zawierającej dwa pola oraz konstruktorkonstruktorkonstruktor:

Linia 1. class Wezel otwórz nawias klamrowy. Linia 2. int liczba średnik. Linia 3. Wezel nastepny średnik. Linia 4. Wezel otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. this kropka liczba znak równości liczba średnik. Linia 6. this kropka nastepny znak równości null średnik. Linia 7. zamknij nawias klamrowy. Linia 8. zamknij nawias klamrowy.

Stworzenie nowego węzła i przypisanie wartości do jego składowych umożliwia instrukcja:

Linia 1. Wezel nowy znak równości new Wezel otwórz nawias okrągły liczba zamknij nawias okrągły średnik.

Stos zaimplementujemy również jako klasę, której atrybutem będzie referencja na wierzchołek stosu o nazwie wierzcholek. Klasa będzie zawierała również definicję konstruktora.

Linia 1. class Stos otwórz nawias klamrowy. Linia 2. Wezel wierzcholek średnik. Linia 4. public Stos otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. wierzcholek znak równości null średnik. Linia 6. zamknij nawias klamrowy. Linia 8. prawy ukośnik prawy ukośnik Miejsce na dodanie metod. Linia 9. zamknij nawias klamrowy.

W konstruktorze Stos() inicjalizujemy pole wierzcholek referencją pustąreferencjareferencją pustą.

Do klasy Stos() dodamy teraz metody wykonujące charakterystyczne dla stosu operacje.

Zaczniemy od metody czyPusty(), która będzie zwracała wartość true (prawda), jeżeli stos będzie pusty, czyli w sytuacji, kiedy pole wierzcholek będzie referencją pustą. W przeciwnym razie metoda zwróci wartość false (fałsz).

Linia 1. public boolean czyPusty otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły wierzcholek znak równości znak równości null zamknij nawias okrągły otwórz nawias klamrowy. Linia 3. System kropka out kropka println otwórz nawias okrągły cudzysłów Stos pusty wykrzyknik cudzysłów zamknij nawias okrągły średnik. Linia 4. zamknij nawias klamrowy. Linia 5. return otwórz nawias okrągły wierzcholek znak równości znak równości null zamknij nawias okrągły średnik. Linia 6. zamknij nawias klamrowy.

W celu zachowania poprawności działania struktury LIFO, funkcja odloz() będzie dodawała elementy na początku listy i odpowiednio funkcja zdjemij() będzie usuwała elementy również z początku listy.

Zacznijmy od metody odloz():

Linia 1. public void odloz otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. System kropka out kropka println otwórz nawias okrągły cudzysłów Odkładam cudzysłów plus String kropka valueOf otwórz nawias okrągły liczba zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 4. Wezel nowy znak równości new Wezel otwórz nawias okrągły liczba zamknij nawias okrągły średnik. Linia 5. nowy kropka nastepny znak równości wierzcholek średnik. Linia 6. wierzcholek znak równości nowy średnik. Linia 7. zamknij nawias klamrowy.

W funkcji odloz() tworzymy nowy węzeł i zapisujemy w nim wartość zmiennej liczba przekazaną jako argument. Następnie pole nastepny nowego elementu ustawiamy na dotychczasowy wierzcholek, w ten sposób dodajemy element na początku listy. Na koniec aktualizujemy pole wierzcholek, tak aby wskazywało na nowo dodany element.

W metodzie pomijamy sprawdzenie ewentualnego błędu przepełnienia stosuprzepełnienie stosuprzepełnienia stosu, który ze względu na użycie listy jest mało prawdopodobny.

Usuwanie pierwszego elementu jest możliwe dzięki referencji wierzcholek:

Linia 1. public int zdejmij otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły czyPusty otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły return Integer kropka MIN podkreślnik VALUE średnik. Linia 3. Wezel pomocniczy znak równości wierzcholek średnik. Linia 4. int liczba znak równości pomocniczy kropka liczba średnik. Linia 5. wierzcholek znak równości wierzcholek kropka nastepny średnik. Linia 7. System kropka out kropka println otwórz nawias okrągły cudzysłów Zdejmuję cudzysłów plus Integer kropka toString otwórz nawias okrągły liczba zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 9. return liczba średnik. Linia 10. zamknij nawias klamrowy.

Jeżeli stos jest pusty, tzn. zachodzi błąd niedopełnienia stosuniedopełnienie stosuniedopełnienia stosu, zwracamy minimalną wartość zdefiniowaną dla typu całkowitego w stałej MIN_VALUE.

W przeciwnym razie dotychczasowy pierwszy element oraz zapisaną w nim wartość zapamiętujemy w zmiennych pomocniczych. Następnie ustawiamy wierzchołek na drugi element listy, dotychczasowy pierwszy usuwamy, a zapamiętaną wartość zwracamy.

Metoda pobierzWierzcholek() ma tylko jedno zadanie: jeżeli stos nie jest pusty, zwraca wartość zapisaną w pierwszym, czyli ostatnim dodanym, elemencie listy:

Linia 1. public int pobierzWierzcholek otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły czyPusty otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły return Integer kropka MIN podkreślnik VALUE średnik. Linia 3. return wierzcholek kropka liczba średnik. Linia 4. zamknij nawias klamrowy.

Metoda wypisz() posłuży do wypisania wartości odłożonych na stosie, czyli zapisanych w kolejnych węzłach listy:

Linia 1. public void wypisz otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły czyPusty otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły return średnik. Linia 4. System kropka out kropka print otwórz nawias okrągły cudzysłów Stos zawiera dwukropek cudzysłów zamknij nawias okrągły średnik. Linia 5. Wezel pomocniczy znak równości wierzcholek średnik. Linia 6. while otwórz nawias okrągły pomocniczy wykrzyknik znak równości null zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. System kropka out kropka print otwórz nawias okrągły pomocniczy kropka liczba plus cudzysłów cudzysłów zamknij nawias okrągły średnik. Linia 8. pomocniczy znak równości pomocniczy kropka nastepny średnik. Linia 9. zamknij nawias klamrowy. Linia 10. System kropka out kropka println otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 11. zamknij nawias klamrowy.

Do wypisania wartości używamy pętli przechodzącej po wszystkich elementach stosu zapisywanych w zmiennej pomocniczy, którą ustawiamy na wierzchołek, a następnie wewnątrz pętli przesuwamy na kolejne węzły wskazywane przez pole nastepny. Pętla będzie działać dopóki nie dojdziemy do ostatniego węzła, którego referencja nastepny będzie pusta.

Do sprawdzenia działania stosu możemy użyć poniższego kodu:

Linia 1. public class StosLista otwórz nawias klamrowy. Linia 2. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 3. Stos stos znak równości new Stos otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 4. stos kropka odloz otwórz nawias okrągły 1 zamknij nawias okrągły średnik. Linia 5. stos kropka odloz otwórz nawias okrągły 2 zamknij nawias okrągły średnik. Linia 6. stos kropka odloz otwórz nawias okrągły 3 zamknij nawias okrągły średnik. Linia 7. stos kropka wypisz otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 8. stos kropka zdejmij otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 9. stos kropka zdejmij otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 10. stos kropka zdejmij otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 11. stos kropka zdejmij otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 12. zamknij nawias klamrowy. Linia 13. zamknij nawias klamrowy.
Ćwiczenie 1

Na podstawie całego omówionego powyżej kodu przygotuj program ilustrujący działanie stosu. Przeanalizuj podaną wyżej funkcję główną i odpowiedz, jaki będzie ostatni wypisany przez program komunikat. Uruchom program i sprawdź poprawność swojej odpowiedzi.

Wykorzystaj omówiony kod i przygotuj program pozwalający sprawdzić działanie kolejki. Dodaj do kolejki trzy liczby, wypisz kolejkę, a następnie cztery raz wywołaj metodę usuwającą.

RJl1aILncO7Yk
sss

Kolejka

Kolejka to liniowa struktura danych typu FIFO (ang. First‑In, First‑Out – pierwszy na wejściu, pierwszy na wyjściu), co oznacza, że jej elementy odczytywane są zgodnie z kolejnością dodawania, a zatem odwrotnie niż w przypadku stosu.

W implementacji kolejki również użyjemy listy jednokierunkowej oraz takiej samej jak w przypadku stosu definicji klasy Wezel. Natomiast klasa Kolejka będzie zawierała dwa pola:

  • glowa – referencję na pierwszy element kolejki;

  • ogon – referencję na ostatni element kolejki, który ułatwi dodawanie elementów na końcu listy.

Nazwy pozostałych metod dostosujemy do omawianej struktury.

Linia 1. class Wezel otwórz nawias klamrowy. Linia 2. int liczba średnik. Linia 3. Wezel nastepny średnik. Linia 4. Wezel otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. this kropka liczba znak równości liczba średnik. Linia 6. this kropka nastepny znak równości null średnik. Linia 7. zamknij nawias klamrowy. Linia 8. zamknij nawias klamrowy. Linia 10. class Kolejka otwórz nawias klamrowy. Linia 11. Wezel glowa średnik. Linia 12. Wezel ogon średnik. Linia 14. public Kolejka otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 15. glowa znak równości ogon znak równości null średnik. Linia 16. zamknij nawias klamrowy. Linia 18. prawy ukośnik prawy ukośnik Miejsce na metody. Linia 19. zamknij nawias klamrowy.

Metoda czyPusta() działa tak samo, jak w przypadku stosu i każdej listy, tzn. jeżeli referencja na pierwszy element jest pusta, lista jest pusta.

Linia 1. public boolean czyPusta otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. return otwórz nawias okrągły glowa znak równości znak równości null zamknij nawias okrągły średnik. Linia 3. zamknij nawias klamrowy.

Metoda dodaj() będzie dodawała nowe elementy na końcu listy przy użyciu pola ogon.

Linia 1. public void dodaj otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. Wezel nowy znak równości new Wezel otwórz nawias okrągły liczba zamknij nawias okrągły średnik. Linia 3. nowy kropka nastepny znak równości null średnik. Linia 5. if otwórz nawias okrągły czyPusta otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. glowa znak równości ogon znak równości nowy średnik. Linia 7. return średnik. Linia 8. zamknij nawias klamrowy. Linia 10. ogon kropka nastepny znak równości nowy średnik. Linia 11. ogon znak równości nowy średnik. Linia 12. zamknij nawias klamrowy.

Na początku metody tworzymy nowy węzeł, przypisujemy otrzymaną liczbę do jego pola liczba, a referencję nastepny ustawiamy na wartość pustą. Następnie, jeżeli lista jest pusta, referencje na pierwszy (glowa) i ostatni (ogon) element listy ustawiamy na nowy węzeł.

W przeciwnym razie referencję nastepny dotychczasowego ostatniego elementu ustawiamy na nowy węzeł i aktualizujemy referencję ogon, aby wskazywał nowo dodany element.

Metoda usun() będzie zwracała kolejne elementy z początku listy, czyli działać będzie tak samo, jak metoda zdejmij() w przypadku stosu. Ponieważ jednak elementy będą dodawane na końcu listy, zasada działania kolejki FIFO zostanie zachowana.

Linia 1. public int usun otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły czyPusta otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły return Integer kropka MIN podkreślnik VALUE średnik. Linia 3. Wezel pomocniczy znak równości glowa średnik. Linia 4. int liczba znak równości pomocniczy kropka liczba średnik. Linia 5. glowa znak równości glowa kropka nastepny średnik. Linia 7. System kropka out kropka println otwórz nawias okrągły cudzysłów Usuwam dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły liczba zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 9. return liczba średnik. Linia 10. zamknij nawias klamrowy.
Ćwiczenie 2

Wykorzystaj omówiony kod i przygotuj program pozwalający sprawdzić działanie kolejki. Dodaj do kolejki trzy liczby, wypisz kolejkę, a następnie cztery raz wywołaj metodę usuwającą.

RJl1aILncO7Yk
sss

Lista

Przypomnijmy, że lista – podobnie jak stos i kolejka – jest liniową i dynamiczną strukturą danych. Elementami listy są węzły, które zawierają dane oraz referencjęreferencjareferencję na element następny (w przypadku listy jednokierunkowej) lub na następny i poprzedni (w przypadku listy dwukierunkowej).

Do implementacji stosu i kolejki użyliśmy listy jednokierunkowej. Jej węzły zdefiniowaliśmy przy użyciu klasyklasaklasy zawierającej dwa pola i konstruktor argumentowy:

Linia 1. class Wezel otwórz nawias klamrowy. Linia 2. int liczba średnik. Linia 3. Wezel nastepny średnik. Linia 5. prawy ukośnik prawy ukośnik Konstruktor argumentowy. Linia 6. Wezel otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. this kropka liczba znak równości liczba średnik. Linia 8. this kropka nastepny znak równości null średnik. Linia 9. zamknij nawias klamrowy. Linia 10. zamknij nawias klamrowy.

Konstruktor argumentowy wymaga podania argumentu podczas tworzenia obiektu, co pozwala zainicjować pole liczba otrzymaną wartością:

Linia 1. prawy ukośnik prawy ukośnik Wykorzystanie konstruktora argumentowego. Linia 2. Wezel wezel znak równości new Wezel otwórz nawias okrągły 1 zamknij nawias okrągły średnik.

Lista jednokierunkowa

Listę jednokierunkową implementujemy jako klasęklasaklasę z jednym polem glowa – wskazującym na pierwszy element listy. Oprócz tego w klasie definiujemy metody umożliwiające dodawanie, usuwanie i wypisywanie elementów listy. W konstruktorze Lista() inicjalizujemy pole glowa referencją pustąreferencjareferencją pustą.

Linia 1. class Lista otwórz nawias klamrowy. Linia 2. Wezel glowa średnik. Linia 4. public Lista otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. glowa znak równości null średnik. Linia 6. zamknij nawias klamrowy. Linia 8. prawy ukośnik prawy ukośnik Miejsce na metody. Linia 9. zamknij nawias klamrowy.

Metody czyPusta() oraz wypisz() działają tak samo jak w przypadku stosu i kolejki. Wyjaśnimy działanie metody dodającej węzły na końcu listy oraz usuwającej węzły o podanej pozycji.

Dodawanie węzłów na końcu listy jednokierunkowej

Metoda dodaj() jako argument będzie przyjmowała liczbę całkowitą. Nowy węzeł – inaczej niż w przypadku stosu i kolejki – będzie dodawany na końcu listy.

Linia 1. public void dodaj otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. System kropka out kropka println otwórz nawias okrągły cudzysłów Dodaję cudzysłów plus String kropka valueOf otwórz nawias okrągły liczba zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 4. prawy ukośnik prawy ukośnik Tworzymy nowy węzeł. Linia 5. Wezel nowy znak równości new Wezel otwórz nawias okrągły liczba zamknij nawias okrągły średnik. Linia 7. prawy ukośnik prawy ukośnik Jeżeli lista jest pusta. Linia 8. if otwórz nawias okrągły czyPusta otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 9. glowa znak równości nowy średnik. Linia 10. return średnik. Linia 11. zamknij nawias klamrowy. Linia 13. prawy ukośnik prawy ukośnik W przeciwnym razie przejdź do ostatniego elementu. Linia 14. Wezel pomocniczy znak równości glowa średnik. Linia 15. while otwórz nawias okrągły pomocniczy kropka nastepny wykrzyknik znak równości null zamknij nawias okrągły otwórz nawias klamrowy. Linia 16. pomocniczy znak równości pomocniczy kropka nastepny średnik. Linia 17. zamknij nawias klamrowy. Linia 19. prawy ukośnik prawy ukośnik Dodajemy nowy węzeł na końcu listy. Linia 20. pomocniczy kropka nastepny znak równości nowy średnik. Linia 21. zamknij nawias klamrowy.

Na początku metody tworzymy nowy węzeł, przekazując do jego konstruktora otrzymaną liczbę. Następnie, jeżeli lista jest pusta, nowy węzeł staje się pierwszym elementem listy przypisanym do pola glowa.

W przeciwnym razie za pomocą węzła pomocniczy w pętli przechodzimy listę do ostatniego elementu, którego referencja nastepny będzie pusta. Po zakończeniu pętli pole nastepny dotychczasowego ostatniego elementu ustawiamy na nowy węzeł. W ten sposób dodajemy węzeł na końcu listy.

R1eSTXiWk4HIn
Schemat dodawania węzła do końca listy jednokierunkowej
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Usuwanie węzłów z listy jednokierunkowej

Metoda usuwająca węzły z listy otrzymywać będzie jako argument liczbę całkowitą wskazującą indeks czy też numer węzła, który chcemy usunąć. Przyjmijmy, że indeksy węzłów zaczynają się od 1.

Linia 1. public void usun otwórz nawias okrągły int indeks zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły czyPusta otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły return średnik. Linia 4. System kropka out kropka println otwórz nawias okrągły cudzysłów Usuwam pozycję dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły indeks zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 6. Wezel pomocniczy1 znak równości glowa przecinek pomocniczy2 znak równości null średnik. Linia 7. int rozmiar znak równości 0 średnik. Linia 9. prawy ukośnik prawy ukośnik Zliczamy elementy listy. Linia 10. while otwórz nawias okrągły pomocniczy1 wykrzyknik znak równości null zamknij nawias okrągły otwórz nawias klamrowy. Linia 11. pomocniczy1 znak równości pomocniczy1 kropka nastepny średnik. Linia 12. rozmiar plus plus średnik. Linia 13. zamknij nawias klamrowy. Linia 14. prawy ukośnik prawy ukośnik Jeżeli indeks jest większy od rozmiaru listy. Linia 15. if otwórz nawias okrągły indeks zamknij nawias ostrokątny rozmiar zamknij nawias okrągły otwórz nawias klamrowy. Linia 16. System kropka out kropka println otwórz nawias okrągły cudzysłów Indeks poza zakresem kropka cudzysłów zamknij nawias okrągły średnik. Linia 17. return średnik. Linia 18. zamknij nawias klamrowy. Linia 20. prawy ukośnik prawy ukośnik Poniżej dodamy kod usuwający elementy. Linia 22. zamknij nawias klamrowy.

Jeżeli lista nie jest pusta, definiujemy zmienne, których używamy w metodzie:

  • referencję pomocniczy1 ustawiamy na pierwszy element listy,

  • referencję pomocniczy2 wykorzystamy przy usuwaniu węzłów innych od pierwszego,

  • zmienna rozmiar posłuży do ustalenia rozmiaru listy.

Następnie zliczamy elementy listy za pomocą pętli while przechodzącej po wszystkich węzłach listy, zaczynając od pierwszego. Po dojściu do ostatniego elementu w zmiennej pomocniczy1 zostanie zapisana wartość null i pętla zakończy swoje działanie.

Ważne!

Warto zapamiętać omówioną pętlę, ponieważ przechodzenie wszystkich elementów listy, zaczynając od pierwszego, jest typową operacją wykonywaną na listach.

Następnie, jeżeli podany indeks nie jest większy od obliczonego rozmiaru listy, zaczynamy usuwanie węzła. Zadanie to realizuje kod, który umieszczamy na końcu omawianej metody:

Linia 1. prawy ukośnik prawy ukośnik Usuwanie pierwszego węzła. Linia 2. if otwórz nawias okrągły indeks znak równości znak równości 1 zamknij nawias okrągły otwórz nawias klamrowy. Linia 3. glowa znak równości glowa kropka nastepny średnik. Linia 4. return średnik. Linia 5. zamknij nawias klamrowy. Linia 7. prawy ukośnik prawy ukośnik Szukanie węzła do usunięcia otwórz nawias okrągły innego niż pierwszy zamknij nawias okrągły. Linia 8. pomocniczy1 znak równości glowa średnik. Linia 9. while otwórz nawias okrągły indeks minus minus zamknij nawias ostrokątny 1 zamknij nawias okrągły otwórz nawias klamrowy. Linia 10. pomocniczy2 znak równości pomocniczy1 średnik. Linia 11. pomocniczy1 znak równości pomocniczy1 kropka nastepny średnik. Linia 12. zamknij nawias klamrowy. Linia 14. prawy ukośnik prawy ukośnik Zmiana pola nastepny węzła poprzedzającego usuwany. Linia 15. pomocniczy2 kropka nastepny znak równości pomocniczy1 kropka nastepny średnik.

Jeżeli usuwanym elementem jest pierwszy węzeł (indeks 1), pole glowa ustawiamy na następny węzeł, co powoduje wyłączenie dotychczasowego pierwszego elementu z listy.

W przeciwnym razie w pętli, która wykonuje się, dopóki indeks jest większy od 1, szukamy węzła do usunięcia. W każdej iteracji indeks jest zmniejszany o 1 dzięki notacji postfiksowej. Wewnątrz pętli przechodzimy po indeks - 1 elementach listy od jej początku, więc po jej zakończeniu zmienna pomocniczy1 będzie wskazywała węzeł do usunięcia, a zmienna pomocniczy2 węzeł poprzedni.

Po zakończeniu pętli w węźle poprzedzającym węzeł usuwany ustawiamy referencję nastepny na węzeł następny po węźle usuwanym (w przypadku usuwania ostatniego węzła będzie to wartość null).

Dla zainteresowanych

W językach programowania Java i Python nie trzeba usuwać węzłów i zwalniać zajmowanych przez niego pamięci za pomocą osobnej instrukcji takiej jak np. wyrażenie delete() w języku C++. Jeżeli na jakiś obiekt nie wskazują żadne referencje, zostanie on usunięty przez mechanizm odśmiecania pamięci (ang. garbage collection).

R1DT71fUbiSfA
Schemat usuwania węzła z listy jednokierunkowej
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.
Ćwiczenie 3

Wykorzystaj omówiony kod i przygotuj program pozwalający sprawdzić działanie listy jednokierunkowej. Dodaj do listy trzy liczby i wypisz listę. Następnie usuń drugi element i wypisz listę. Na końcu jeszcze raz usuń drugi element, dodaj liczbę i wypisz listę.

R1Og0RiM25SjP
2

Lista dwukierunkowa

Lista dwukierunkowa od jednokierunkowej różni się tym, że jej węzły – oprócz referencji na element następny – zawierają także referencję na element poprzedni. Implementację przygotujemy, korzystając z omówionego kodu listy jednokierunkowej.

Na początku uzupełniamy klasę Wezel o pole poprzedni i uzupełniamy konstruktor tak, aby inicjalizował je wartością pustą. Do klasy Lista dodajemy pole ogon, które będzie wskazywało ostatni element listy. W konstruktorze klasy pola glowaogon ustawiamy na wartości puste.

Linia 1. class Wezel otwórz nawias klamrowy. Linia 2. int liczba średnik. Linia 3. Wezel nastepny średnik. Linia 4. Wezel poprzedni średnik. Linia 6. Wezel otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 7. this kropka liczba znak równości liczba średnik. Linia 8. this kropka nastepny znak równości null średnik. Linia 9. this kropka poprzedni znak równości null średnik. Linia 10. zamknij nawias klamrowy. Linia 11. zamknij nawias klamrowy. Linia 13. class Lista otwórz nawias klamrowy. Linia 14. Wezel glowa średnik. Linia 15. Wezel ogon średnik. Linia 17. public Lista otwórz nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 18. glowa znak równości ogon znak równości null średnik. Linia 19. zamknij nawias klamrowy. Linia 21. prawy ukośnik prawy ukośnik Poniżej dodamy kolejne metody. Linia 22. zamknij nawias klamrowy.

Pole ogon, tj. referencja na ostatni element listy, jest opcjonalne – może występować zarówno w listach jedno-, jak i dwukierunkowych. Używa się go m.in. do szybkiego dodawania elementów na końcu listy bez konieczności przechodzenia po wszystkich jej elementach w celu znalezienia ostatniego.

Dodawanie węzłów na końcu listy dwukierunkowej

Metody czyPusta() oraz wypisz() pozostają bez zmian. Modyfikacji wymagają tylko implementacje metod dodaj()usun(). Zacznijmy od metody dodającej nowe węzły:

Linia 1. public void dodaj otwórz nawias okrągły int liczba zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. System kropka out kropka println otwórz nawias okrągły cudzysłów Dodaję cudzysłów plus String kropka valueOf otwórz nawias okrągły liczba zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 4. Wezel nowy znak równości new Wezel otwórz nawias okrągły liczba zamknij nawias okrągły średnik. Linia 6. prawy ukośnik prawy ukośnik jeżeli lista jest pusta. Linia 7. if otwórz nawias okrągły czyPusta otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 8. glowa znak równości ogon znak równości nowy średnik. Linia 9. return średnik. Linia 10. zamknij nawias klamrowy. Linia 12. prawy ukośnik prawy ukośnik dodanie nowego węzła na końcu listy. Linia 13. ogon kropka nastepny znak równości nowy średnik. Linia 14. nowy kropka poprzedni znak równości ogon średnik. Linia 15. ogon znak równości nowy średnik. Linia 16. zamknij nawias klamrowy.

Różnice w porównaniu do implementacji tej metody w przypadku listy jednokierunkowej są następujące:

  • ustawienia pola ogon na nowy węzeł w przypadku dodawania pierwszego elementu listy,

  • wykorzystanie pola ogon – zamiast pętli przechodzącej wszystkie elementy listy – do wskazania ostatniego węzła listy,

  • ustawienie referencji nastepny dotychczasowego ostatniego węzła na nowy oraz poprzedni nowego węzła na dotychczasowy ostatni,

  • ustawienie pola ogon na nowo dodany element.

RlhFi1x6RJLwH
Schemat dodawania węzła do końca listy dwukierunkowej
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Usuwanie węzłów z listy dwukierunkowej

Metoda usuwająca elementy z podanej pozycji nie wymaga zmian, lecz uzupełnienia. Jeżeli usuwamy element niebędący ani pierwszym, ani ostatnim, musimy odpowiednio ustawić referencję poprzedni węzła występującego po węźle usuwanym. W przeciwnym razie, jeżeli usuwamy ostatni element, musimy zaktualizować pole ogon, aby wskazywało na dotychczasowy węzeł przedostatni. Poniżej kod uzupełnionej metody usun(). W komentarzu zaznaczyliśmy instrukcję warunkową realizującą omówione operacje:

Linia 1. public void usun otwórz nawias okrągły int indeks zamknij nawias okrągły otwórz nawias klamrowy. Linia 2. if otwórz nawias okrągły czyPusta otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły return średnik. Linia 4. System kropka out kropka println otwórz nawias okrągły cudzysłów Usuwam pozycję dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły indeks zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 6. Wezel pomocniczy1 znak równości glowa przecinek pomocniczy2 znak równości null średnik. Linia 7. int rozmiar znak równości 0 średnik. Linia 9. while otwórz nawias okrągły pomocniczy1 wykrzyknik znak równości null zamknij nawias okrągły otwórz nawias klamrowy. Linia 10. pomocniczy1 znak równości pomocniczy1 kropka nastepny średnik. Linia 11. rozmiar plus plus średnik. Linia 12. zamknij nawias klamrowy. Linia 14. if otwórz nawias okrągły indeks zamknij nawias ostrokątny rozmiar zamknij nawias okrągły otwórz nawias klamrowy. Linia 15. System kropka out kropka println otwórz nawias okrągły cudzysłów Indeks poza zakresem kropka cudzysłów zamknij nawias okrągły średnik. Linia 16. return średnik. Linia 17. zamknij nawias klamrowy. Linia 19. if otwórz nawias okrągły indeks znak równości znak równości 1 zamknij nawias okrągły otwórz nawias klamrowy. Linia 20. glowa znak równości glowa kropka nastepny średnik. Linia 21. return średnik. Linia 22. zamknij nawias klamrowy. Linia 24. pomocniczy1 znak równości glowa średnik. Linia 25. while otwórz nawias okrągły indeks minus minus zamknij nawias ostrokątny 1 zamknij nawias okrągły otwórz nawias klamrowy. Linia 26. pomocniczy2 znak równości pomocniczy1 średnik. Linia 27. pomocniczy1 znak równości pomocniczy1 kropka nastepny średnik. Linia 28. zamknij nawias klamrowy. Linia 30. pomocniczy2 kropka nastepny znak równości pomocniczy1 kropka nastepny średnik. Linia 32. prawy ukośnik prawy ukośnik Kod obsługujący listę dwukierunkową. Linia 33. if otwórz nawias okrągły pomocniczy1 kropka nastepny wykrzyknik znak równości null zamknij nawias okrągły otwórz nawias klamrowy. Linia 34. prawy ukośnik prawy ukośnik Jeżeli usuwany węzeł nie jest ostatni. Linia 35. pomocniczy1 kropka nastepny kropka poprzedni znak równości pomocniczy2 średnik. Linia 36. zamknij nawias klamrowy else otwórz nawias klamrowy. Linia 37. prawy ukośnik prawy ukośnik Jeżeli usuwany element jest ostatni. Linia 38. ogon znak równości pomocniczy2 średnik. Linia 39. zamknij nawias klamrowy. Linia 40. zamknij nawias klamrowy.
R50oTO05RitRz
Schemat usuwania węzła z listy dwukierunkowej
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.
Ćwiczenie 4

Wykorzystaj omówiony kod i przygotuj program pozwalający sprawdzić działanie listy dwukierunkowej. Dodaj do listy trzy liczby i wypisz listę. Następnie usuń pierwszy, drugi i trzeci element. Dodaj do listy jeszcze jedną liczbę i wypisz listę.

RUHeK9ZkbEYI9
2

Stos, kolejka i lista w Java Collections Framework

Dla zainteresowanych

Java Collections FrameworkJava Collections Framework Java Collections Framework to zestaw interfejsów oraz implementacji przeznaczonych do tworzenia omawianych wyżej struktur dynamicznych. Interfejsy w języku Java definiują abstrakcyjne metody i pola, które muszą zostać zaimplementowane w konkretnej klasie służącej do tworzenia danej kolekcji. Omawiane w materiale struktury można tworzyć za pomocą różnych interfejsów i klas.

Interfejs Deque i klasa ArrayDeque

Java Collections Framework definiuje klasę Stack będącą implementacją struktury stosu. Jednak ze względu na jej ograniczenia, m.in. dziedziczenie z niewspieranej już klasy Vector, zaleca się używanie interfejsu Deque i wybranej jego implementacji. Nazwa interfejsu Deque jest skrótem od wyrażenia double ended queue, które oznacza kolejkę dwukierunkową. Jedną z implementacji tego interfejsu jest klasa ArrayDeque, wykorzystująca dynamiczne tablice. Klasa ta implementuje m.in. następujące metody interfejsu:

  • push() – zadaniem metody jest umieszczenie elementu na stosie;

  • pop() – metoda usuwa pierwszy element kolejki;

  • getFirst() – metoda zwraca bez usuwania pierwszy element kolekcji;

  • peek() – zadaniem metody jest pobranie wierzchołka stosu;

  • isEmpty() – metoda sprawdza, czy stos jest pusty;

  • size() – zadaniem metody jest zwrócenie liczby elementów na stosie.

Przykład 1

Przykładowy program:

Linia 1. import java kropka util kropka Deque średnik. Linia 2. import java kropka util kropka ArrayDeque średnik. Linia 4. public class StosJF otwórz nawias klamrowy. Linia 5. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. Deque otwórz nawias ostrokątny Integer zamknij nawias ostrokątny stos znak równości new ArrayDeque otwórz nawias ostrokątny zamknij nawias ostrokątny otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 8. System kropka out kropka println otwórz nawias okrągły cudzysłów Odkładam liczby 5 przecinek 4 przecinek 6 cudzysłów zamknij nawias okrągły średnik. Linia 9. stos kropka push otwórz nawias okrągły 5 zamknij nawias okrągły średnik. Linia 10. stos kropka push otwórz nawias okrągły 4 zamknij nawias okrągły średnik. Linia 11. stos kropka push otwórz nawias okrągły 6 zamknij nawias okrągły średnik. Linia 12. System kropka out kropka print otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły stos kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 13. System kropka out kropka println otwórz nawias okrągły cudzysłów Wierzchołek dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły stos kropka getFirst otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 15. System kropka out kropka println otwórz nawias okrągły cudzysłów Zdejmuję wierzchołek dwukropek cudzysłów plus stos kropka pop otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 16. System kropka out kropka print otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły stos kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 17. System kropka out kropka println otwórz nawias okrągły cudzysłów Wierzchołek dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły stos kropka getFirst otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 19. System kropka out kropka print otwórz nawias okrągły cudzysłów Stos zawiera dwukropek cudzysłów zamknij nawias okrągły średnik. Linia 20. while otwórz nawias okrągły wykrzyknik stos kropka isEmpty otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 21. System kropka out kropka print otwórz nawias okrągły stos kropka peek otwórz nawias okrągły zamknij nawias okrągły plus cudzysłów cudzysłów zamknij nawias okrągły średnik. Linia 22. stos kropka pop otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 23. zamknij nawias klamrowy. Linia 24. System kropka out kropka println otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 26. System kropka out kropka println otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły stos kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 27. zamknij nawias klamrowy. Linia 28. zamknij nawias klamrowy.

Na początku tworzymy obiekt stos do przechowywania wartości typu Integer (liczby całkowite). Następnie odkładamy na stosie trzy liczby za pomocą metody push, która dodaje je na początku listy. Następnie wypisujemy rozmiar (size()) i wierzchołek (getFirst()) stosu.

W kolejnych instrukcjach zdejmujemy wierzchołek ze stosu (pop()), wypisujemy rozmiar i nowy wierzchołek.

Na końcu przy użyciu pętli wykonującej się, dopóki stos nie jest pusty (isEmpty()), wypisujemy kolejny wierzchołek (peek()) i zdejmujemy go. Na końcu wypisujemy jeszcze raz aktualny rozmiar stosu.

Wynik działania programu:

Linia 1. Odkładam liczby 5 przecinek 4 przecinek 6. Linia 2. Rozmiar dwukropek 3 Wierzchołek dwukropek 6. Linia 3. Zdejmuję wierzchołek kropka. Linia 4. Rozmiar dwukropek 2 Wierzchołek dwukropek 4. Linia 5. Stos zawiera dwukropek 4 5. Linia 6. Rozmiar dwukropek 0.

Interfejs Queue i klasa LinkedList

Interfejs Queue definiuje metody dla typowych kolejek typu FIFO, kolejek priorytetowych oraz kolekcji typu LIFO (typu stos). Jedną z implementacji interfejsu dostarcza klasa LinkedList. Do dyspozycji mamy m.in. następujące metody:

  • add() – zadaniem metody jest dodawanie elementu na końcu listy;

  • remove() – metoda usuwa pierwszy element listy;

  • peek() – metoda zwraca pierwszy element listy bez usuwania go;

  • size() – zadaniem metody jest zwrócenie liczby elementów listy.

Ważne!

Jeżeli do deklarowania typu struktury wykorzystujemy interfejs, ogranicza on dostępne metody, nawet jeżeli implementująca go klasa zawiera ich więcej. Na przykład klasa LinkedList definiuje ponad 30 metod do wykonywania różnych operacji na liście dwukierunkowej, ale użycie interfejsu Queue umożliwia nam wykorzystanie tylko kilku z nich przeznaczonych do obsługi kolejki.

Przykład 2

Przykładowy program:

Linia 1. import java kropka util kropka Queue średnik. Linia 2. import java kropka util kropka LinkedList średnik. Linia 4. public class KolejkaJF otwórz nawias klamrowy. Linia 5. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 6. Queue otwórz nawias ostrokątny Integer zamknij nawias ostrokątny kolejka znak równości new LinkedList otwórz nawias ostrokątny zamknij nawias ostrokątny otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 8. System kropka out kropka println otwórz nawias okrągły cudzysłów Dodaję liczby 5 przecinek 4 przecinek 6 cudzysłów zamknij nawias okrągły średnik. Linia 9. kolejka kropka add otwórz nawias okrągły 5 zamknij nawias okrągły średnik. Linia 10. kolejka kropka add otwórz nawias okrągły 4 zamknij nawias okrągły średnik. Linia 11. kolejka kropka add otwórz nawias okrągły 6 zamknij nawias okrągły średnik. Linia 12. System kropka out kropka print otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły kolejka kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 13. System kropka out kropka println otwórz nawias okrągły cudzysłów Pierwszy dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły kolejka kropka peek otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 15. System kropka out kropka println otwórz nawias okrągły cudzysłów Usuwam pierwszy kropka cudzysłów zamknij nawias okrągły średnik. Linia 16. kolejka kropka remove otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 17. System kropka out kropka print otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły kolejka kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 18. System kropka out kropka println otwórz nawias okrągły cudzysłów Pierwszy dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły kolejka kropka peek otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 20. System kropka out kropka print otwórz nawias okrągły cudzysłów kolejka zawiera dwukropek cudzysłów zamknij nawias okrągły średnik. Linia 21. while otwórz nawias okrągły kolejka kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias ostrokątny 0 zamknij nawias okrągły otwórz nawias klamrowy. Linia 22. System kropka out kropka print otwórz nawias okrągły kolejka kropka peek otwórz nawias okrągły zamknij nawias okrągły plus cudzysłów cudzysłów zamknij nawias okrągły średnik. Linia 23. kolejka kropka remove otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 24. zamknij nawias klamrowy. Linia 25. System kropka out kropka println otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 27. System kropka out kropka println otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły kolejka kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 28. zamknij nawias klamrowy. Linia 29. zamknij nawias klamrowy.

Na początku tworzymy obiekt kolejka, który posłuży do przechowywania wartości typu Integer (liczby całkowite). Następnie dodajemy do kolejki trzy liczby (add) po czym wypisujemy rozmiar (size()) oraz pierwszy (peek()) element.

Następnie usuwamy pierwszy element (remove()) oraz wypisujemy rozmiar oraz pierwszy element kolejki.

Na końcu przy użyciu pętli wykonującej się, dopóki kolejka nie jest pusta (size() > 0), wypisujemy kolejne pierwsze elementy i usuwamy je. Na końcu wypisujemy jeszcze raz aktualny rozmiar kolejki.

Wynik działania programu:

Linia 1. Dodaję liczby 5 przecinek 4 przecinek 6. Linia 2. Rozmiar dwukropek 3 Pierwszy dwukropek 5. Linia 3. Usuwam pierwszy kropka. Linia 4. Rozmiar dwukropek 2 Pierwszy dwukropek 4. Linia 5. kolejka zawiera dwukropek 4 6. Linia 6. Rozmiar dwukropek 0.

Klasa LinkedList

Klasa LinkedList implementuje interfejsy Queue, Deque oraz List za pomocą listy dwukierunkowej, której elementami są węzły. Klasa udostępnia wszystkie opcjonalne metody wspomnianych interfejsów, m.in.:

  • add() – zadaniem metody jest dodawanie elementu na końcu listy;

  • remove() – metoda usuwa pierwszy element listy;

  • peek() – metoda zwraca pierwszy element bez usuwania go;

  • addLast() – zadaniem metody jest dodawanie elementu na końcu listy;

  • addFirst() – metoda odpowiada za dodawanie elementu na początku listy;

  • removeLast() – metoda usuwa ostatni element listy;

  • removeFirst() – zadaniem metody jest usuwanie pierwszego elementu listy;

  • peekLast() – metoda zwraca ostatni elementu listy bez usuwania go;

  • peekFirst() – działanie metody polega na zwracaniu pierwszego elementu listy bez usuwania go;

  • get(index) – metoda zwraca węzeł o podanym indeksie bez usuwania go;

  • isEmpty() – metoda podaje informację, czy lista jest pusta;

  • size() – metoda odpowiada za podanie rozmiaru listy.

Przykład 3

Przykładowy program:

Linia 1. import java kropka util kropka LinkedList średnik. Linia 3. public class ListaJF otwórz nawias klamrowy. Linia 4. public static void main otwórz nawias okrągły String otwórz nawias kwadratowy zamknij nawias kwadratowy args zamknij nawias okrągły otwórz nawias klamrowy. Linia 5. LinkedList otwórz nawias ostrokątny Integer zamknij nawias ostrokątny lista znak równości new LinkedList otwórz nawias ostrokątny zamknij nawias ostrokątny otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 7. System kropka out kropka println otwórz nawias okrągły cudzysłów Dodaję liczby 5 przecinek 4 na końcu cudzysłów zamknij nawias okrągły średnik. Linia 8. lista kropka add otwórz nawias okrągły 5 zamknij nawias okrągły średnik. Linia 9. lista kropka addLast otwórz nawias okrągły 4 zamknij nawias okrągły średnik. Linia 10. System kropka out kropka println otwórz nawias okrągły cudzysłów Dodaję liczbę 6 na początku cudzysłów zamknij nawias okrągły średnik. Linia 11. lista kropka addFirst otwórz nawias okrągły 6 zamknij nawias okrągły średnik. Linia 12. System kropka out kropka print otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 13. System kropka out kropka print otwórz nawias okrągły cudzysłów Pierwszy dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka peekFirst otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 14. System kropka out kropka println otwórz nawias okrągły cudzysłów Ostatni dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka peekLast otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 16. System kropka out kropka println otwórz nawias okrągły cudzysłów Usuwam ostatni kropka cudzysłów zamknij nawias okrągły średnik. Linia 17. lista kropka removeLast otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 18. System kropka out kropka print otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 19. System kropka out kropka print otwórz nawias okrągły cudzysłów Pierwszy dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka peekFirst otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 20. System kropka out kropka println otwórz nawias okrągły cudzysłów Ostatni dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka peekLast otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 22. System kropka out kropka print otwórz nawias okrągły cudzysłów Lista zawiera dwukropek cudzysłów zamknij nawias okrągły średnik. Linia 23. while otwórz nawias okrągły wykrzyknik lista kropka isEmpty otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły otwórz nawias klamrowy. Linia 24. System kropka out kropka print otwórz nawias okrągły lista kropka peek otwórz nawias okrągły zamknij nawias okrągły plus cudzysłów cudzysłów zamknij nawias okrągły średnik. Linia 25. lista kropka remove otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 26. zamknij nawias klamrowy. Linia 27. System kropka out kropka println otwórz nawias okrągły zamknij nawias okrągły średnik. Linia 29. System kropka out kropka println otwórz nawias okrągły cudzysłów Rozmiar dwukropek cudzysłów plus Integer kropka toString otwórz nawias okrągły lista kropka size otwórz nawias okrągły zamknij nawias okrągły zamknij nawias okrągły zamknij nawias okrągły średnik. Linia 30. zamknij nawias klamrowy. Linia 31. zamknij nawias klamrowy.

Na początku tworzy obiekt lista, który posłuży do przechowywania wartości typu int (liczby całkowite). Następnie dodajemy na końcu listy dwie liczby (add(), addLast()), następnie jedną na początku (addFirst()), po czym wypisujemy rozmiar (size()) oraz pierwszy (peekFirst()) i ostatni (peekLast()) element.

Następnie usuwamy ostatni element (removeLast()) oraz wypisujemy rozmiar, pierwszy i ostatni element listy.

Na końcu przy użyciu pętli wykonującej się, dopóki lista nie jest pusta (isEmpty()), wypisujemy kolejne pierwsze elementy (peek()) i usuwamy je (remove()). Na końcu wypisujemy jeszcze raz aktualny rozmiar listy.

Wynik działania programu:

Linia 1. Dodaję liczby 5 przecinek 4 na końcu. Linia 2. Dodaję liczbę 6 na początku. Linia 3. Rozmiar dwukropek 3 Pierwszy dwukropek 6 Ostatni dwukropek 4. Linia 4. Usuwam ostatni kropka. Linia 5. Rozmiar dwukropek 2 Pierwszy dwukropek 6 Ostatni dwukropek 5. Linia 6. Lista zawiera dwukropek 6 5. Linia 7. Rozmiar dwukropek 0.

Słownik

Java Collections Framework
Java Collections Framework

zestaw interfejsów i klas, które implementują najczęściej używane struktury danych, czyli kolekcje, np. stos, kolejka, lista; mimo określenia framework omawiany zestaw traktować można jak bibliotekę zawierającą gotowe do użycia implementacje

klasa
klasa

definiowany przez użytkownika złożony typ danych, który pozwala grupować logicznie powiazane dane oraz funkcje wykonujące na nich operacje; składowe klasy nazywamy polami, funkcje zdefiniowane w klasie nazywa się metodami

konstruktor
konstruktor

metoda o takie samej nazwie jak klasa, która służy do nadawania wartości początkowych jej polom; w języku Java klasa może mieć wiele konstruktorów dzięki mechanizmowi przeciążania

niedopełnienie stosu
niedopełnienie stosu

(ang. stack underflow) – rodzaj błędu występującego kiedy program próbuje zdjąć wartość z pustego stosu.

przepełnienie stosu
przepełnienie stosu

(ang. stack overflow) – rodzaj błędu polegającego na przekroczeniu rozmiaru pamięci zarezerwowanej dla stosu.

referencja
referencja

zmienna zawierająca informacje o położeniu jakiejś wartości (obiektu) w pamięci; referencje zarządzane są przez kompilator lub interpreter, a nie przez programistę, dzięki czemu są bezpieczniejsze niż wskaźniki; referencje mogą być puste, co znaczy, że nie wskazują na żaden obiekt, w języku Java wyraża to wartość null, w języku Python None

wskaźnik
wskaźnik

zmienna przechowująca adres innej zmiennej lub obiektu, pozwalająca na bezpośredni dostęp do pamięci; możliwe jest tworzenie wskaźników pustych, które na nic nie wskazują