Monthly Archive Marzec 2020

ByKamil

Drzewa poszukiwań binarnych BST

Drzewo – definicja

Pojęcie drzewa wywodzi się z teorii grafów. Jest to graf nieskierowany, acykliczny i spójny. Oznacza to, że do każdego wierzchołka prowadzi krawędź, a graf nie posiada cykli (każde dwa wierzchołki łączy tylko jedna droga prosta). Wpis jest częścią artykułów o kolekcjach w Javie.

Read More

ByKamil

Kolekcje Javy – Interfejs Queue

W artykule o kolejkach przedstawiliśmy podstawowe operacje oraz budowę kolejek. Podobnie jak w przypadku list nie trzeba implementować algorytmów na własną rękę i można skorzystać z biblioteki udostępnionej przez Javę. Istnieje wiele implementacji interfejsów Queue oraz Deque.

Read More

ByKamil

Implementacja listy wiązanej dwukierunkowej

Implementacja listy dwukierunkowej w Javie

Nasza lista jest zbudowana z dwóch klas.

  • Wezel – klasa wewnętrzna – reprezentuje pojedynczy węzeł na liście.
  • Lista – klasa zewnętrzna – zawiera algorytmy dodawania, usuwania oraz wyświetlania elementów oraz przechowuje pierwszy element listy.

Lista ta powstała w celu dydaktycznym, aby pokazać jak wygląda własne opracowanie algorytmu. W związku z tym nie implementujemy żadnych interfejsów, takich jak Comparable, który mógłby posłużyć do sortowania elementów. Z tego samego powodu nie jest to również klasa generyczna, dlatego nie można w tej kolekcji przechowywać żadnych typów własnych, ani innych typów prostych niż int.

Naszym celem było napisanie jak najprostszego algorytmu, aby skupić się na działaniu tej konkretnej struktury danych. Tak, aby w praktyczny sposób przekazać wiedzę z naszego teoretycznego wstępu odnośnie list dwukierunkowych. Polecamy również zapoznać się z implementacją listy jednokierunkowej. Pozornie obie wydają się podobne, jednakże różnią się znacznie przy samej budowie. Znacznie zmieniony jest również algorytm przechodzenia przez nie.

Typem danych do przechowywania jest int. Aby uruchomić poniższy kod należy skopiować kod, a następnie skompilować.

Wewnętrzna klasa Wezel

Powyższy program można podzielić na dwie części. Pierwszą jest obiekt, który przechowuje dane i jest nią klasa Wezel. Ze względu na to, że ta struktura danych jest mało elastyczna umieściliśmy ją wewnątrz klasy Lista, gdyż i tak nie wykorzystamy jej nigdzie indziej. Takie podejście jest wygodnie, ponieważ mamy ułatwiony dostęp do pól obu klas.

Pola

Obiekt klasy Wezel zawiera dwie referencje do innych obiektów oraz zmienną przechowującą dane.

Konstruktor

Inicjuje dane – pola obiektowe czyli referencje do poprzednie i następnego obiektu ustawia na null, a pole z danymi uzupełnia wartością przekazaną w argumencie.

Zewnętrzna klasa Lista

Obiekt klasy Lista przechowuje referencję do pierwszego elementu listy, czyli głowę (ang. head). Zawiera również niezbędne algorytmy, takie jak:

  • dodawanie elementów do listy,
  • usuwanie elementów z listy,
  • szukanie elementu o konkretnym indeksie,
  • wypisanie wszystkich elementów listy.

W metodzie main znajduje się przykładowy przebieg programu. Dane zostały dobrane w taki sposób, aby nie spowodować wyjątku. Wykonanie metody main spowoduje wyświetlenie następujących komunikatów w konsoli.

Zachęcamy do eksperymentów z kodem.

Metody

Wielokrotne wykorzystanie kodu pozytywnie wpływa na jego objętość. Lista dwukierunkowa pozwala na ponowne wykorzystanie metody getWezel() w celu znalezienia usuwanego węzła zamiast pisać ponownie kod, który robi tę samą czynność.

Wyjątek IndexOutOfBoundException

Jeżeli spróbujemy wpisać do metody szukającej indeks ujemny lub spoza naszej listy zostanie wyrzucony wyjątek.

System zbierania nieużytków (ang. Garbage collector)

Być może programiści innych języków zwrócili uwagę na to, że po usunięciu elementów nie czyścimy ręcznie pamięci. W językach z rodziny C oprócz zmiany wskaźników na odpowiednie elementy należy użyć funkcji free(), która czyści pamięć – w przeciwnym wypadku po wyjściu z funkcji usuwania elementu stracimy wskaźnik na usuwany element i nigdy już go nie będziemy w stanie usunąć – do restartu maszyny.

W Javie jeśli nie mamy dostępu do obiektu, to nie musimy z tym nic robić. System zbierania nieużytków zrobi wszystko za nas i oczyści pamięć ze zbędnych obiektów.

ByKamil

Kolejki FIFO, LIFO i priorytetowe

Kolejki są kolejnym abstrakcyjnym typem danych, który należy poznać. Ich główną cechą jest dostęp do danych możliwy jedynie z jej początku lub końca – nigdy ze środka. Ich zastosowanie w informatyce jest szerokie – od użycia w algorytmach, po wykorzystanie w pracy systemu np. czas procesora dla poszczególnych procesów, albo kolejka do wydruku na jednej drukarce, gdy obsługuje ona całe piętro. Głównym ich zadaniem jest porządkowanie zbioru w określonej wcześniej kolejności (np. kolejne punkty zadania, które nie mogą być wykonane współbieżnie). Artykuł jest częścią wpisów o kolekcjach w Javie.

Read More

ByKamil

Kolekcje Javy – Interfejs List – LinkedList

W jednym z naszych wpisów poznaliśmy bliskiego krewnego tablic, a mianowicie klasę ArrayList. Jej budowę, sposób działania oraz metody, które pozwalają na praktyczne korzystanie z niej. Implementacja klasy ArrayList daje świetne efekty jeśli chodzi o wyszukiwanie elementów(wszystkie są obok siebie) oraz zamortyzowany koszt dodawania elementów (pojemność kolekcji jest nieco większa niż liczba elementów). Jednak problemem jest dodawanie wielu elementów oraz usuwanie ze środka listy. Wpis jest częścią artykułów o kolekcjach w Javie.

Read More

ByKamil

Kolekcje Javy – Interfejs List – ArrayList

W tym artykule przyjrzymy się gotowym kolekcjom opartych na interfejsie List. Obie omawiane klasy implementują go oraz interfejs Iterable w związku z tym ich obsługa z puntu widzenia programisty będzie bardzo podobna. Różnice polegają głównie na sposobie reprezentacji danych w pamięci i algorytmów obsługi takich jak dodawanie elementów, odczyt czy też usuwanie. Wpis jest częścią artykułów o kolekcjach w Javie.

Read More

ByKamil

Listy jako struktura danych

Naszą podróż po kolekcjach w Javie zaczniemy od Klas implementujących interfejs List czyli od list.

Czym są listy?

Listy są liniowymi strukturami danych o dynamicznym rozmiarze co oznacza, że mogą zmieniać swój rozmiar w czasie działania programu (w przeciwieństwie do tablic). Najważniejszymi pojęciami, które należy znać są:

  • głowa (ang. head) – początek listy,
  • następny węzeł (ang. next node) – następny element listy,
  • poprzedni węzeł (ang. prev node) – poprzedni element listy.

W zależności od tego czy lista jest jednokierunkowa czy dwukierunkowa, ostatni element jest opcjonalny.

Read More

ByKamil

Kolekcje w Javie

Poprzedni wpis dotyczył interfejsów.

W języku C standardowo jesteśmy ograniczeni do tablic, które w momencie kompilacji muszą mieć zdefiniowany rozmiar. Java w swojej bibliotece standardowej posiada wiele implementacji interfejsów kolekcji np. List, które mogą przyjmować elementy różnych typów. Są to implementacje różnych znanych struktur danych, takich jak lista łączona dwukierunkowa (ang. Linked List) i lista tablicowa (ang. Array List).

Read More

ByKamil

Interfejsy w Javie

Poprzednio omówiliśmy takie elementy dziedziczenia jak hierarchia, klasy abstrakcyjne oraz rzutowanie obiektów.

Teraz poszerzymy nasz warsztat programistyczny o kolejny ważny element, a są nim interfejsy (ang. interface). Słowo interfejs ma wiele znaczeń, ale w poniższym opracowaniu należy je rozumieć jako szereg wymagań jaki musi spełnić klasa, aby móc zapewnić, że implementuje interfejs (co powinna robić, aby być z nim zgodna), ale nie mówiąc zupełnie nic na temat sposobu w jaki to ma się odbywać.

Read More